oh-my-opencode 5.0.0-beta.3 → 5.0.0-beta.31

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 (639) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  4. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  5. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  6. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  7. package/.opencode/command/publish.md +44 -16
  8. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  9. package/README.ja.md +25 -21
  10. package/README.ko.md +25 -21
  11. package/README.md +38 -23
  12. package/README.ru.md +24 -20
  13. package/README.zh-cn.md +25 -21
  14. package/dist/agents/atlas/agent.d.ts +0 -1
  15. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  16. package/dist/agents/sisyphus/index.d.ts +2 -0
  17. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  18. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  19. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  22. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  23. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  24. package/dist/cli/index.js +22601 -20302
  25. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  26. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  27. package/dist/cli/runtime-commands.d.ts +1 -1
  28. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  29. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  30. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  31. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  32. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  34. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  35. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  36. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  37. package/dist/cli-node/index.js +22219 -19897
  38. package/dist/config/schema/background-task.d.ts +1 -0
  39. package/dist/config/schema/commands.d.ts +1 -1
  40. package/dist/config/schema/hooks.d.ts +1 -1
  41. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -1
  42. package/dist/config/schema/ulw-execute.d.ts +5 -0
  43. package/dist/config/validate.d.ts +2 -0
  44. package/dist/create-hooks.d.ts +3 -1
  45. package/dist/features/background-agent/constants.d.ts +0 -7
  46. package/dist/features/background-agent/manager.d.ts +2 -1
  47. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  48. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  49. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  50. package/dist/features/btw-side/context-injector.d.ts +15 -0
  51. package/dist/features/btw-side/index.d.ts +8 -0
  52. package/dist/features/btw-side/metadata.d.ts +15 -0
  53. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  54. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  55. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  56. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  57. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  58. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  59. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  60. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  61. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  62. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  63. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  64. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  65. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  66. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  67. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  68. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  69. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  70. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  71. package/dist/features/builtin-commands/types.d.ts +1 -1
  72. package/dist/features/opengateway-provider/index.d.ts +13 -0
  73. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  74. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
  75. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  76. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  77. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  78. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  79. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  80. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  81. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  82. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  83. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  84. package/dist/hooks/atlas/types.d.ts +1 -0
  85. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  86. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  87. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  88. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  89. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  90. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  91. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  92. package/dist/hooks/index.d.ts +1 -1
  93. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  94. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  95. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  96. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  97. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  98. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  99. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  100. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  101. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  102. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  103. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  104. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  105. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  106. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  107. package/dist/index.js +12989 -7152
  108. package/dist/oh-my-opencode.schema.json +20 -2
  109. package/dist/plugin/chat-message/types.d.ts +3 -3
  110. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  111. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  112. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  113. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  114. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  115. package/dist/plugin/messages-transform.d.ts +1 -0
  116. package/dist/plugin-dispose.d.ts +3 -0
  117. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  118. package/dist/shared/index.d.ts +2 -0
  119. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  120. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  121. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  122. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  123. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  124. package/dist/shared/shell-env.d.ts +1 -1
  125. package/dist/skills/ast-grep/AGENTS.md +51 -0
  126. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  127. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  128. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  129. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  130. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  131. package/dist/skills/data-scientist/SKILL.md +99 -239
  132. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  133. package/dist/skills/data-scientist/references/placement.md +74 -0
  134. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  135. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  136. package/dist/skills/data-scientist/references/visualization.md +64 -0
  137. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  138. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  139. package/dist/skills/debugging/SKILL.md +2 -0
  140. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  141. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  142. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  143. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  144. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  145. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  146. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  147. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  148. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  149. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  150. package/dist/skills/debugging/references/tools/dap.md +103 -0
  151. package/dist/skills/debugging/references/tools/frida.md +193 -0
  152. package/dist/skills/frontend/SKILL.md +11 -7
  153. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  154. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  155. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  156. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  157. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  158. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  159. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  160. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  161. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  162. package/dist/skills/review-work/SKILL.md +3 -3
  163. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  164. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  165. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  166. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  167. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  168. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  169. package/dist/skills/ulw-plan/SKILL.md +6 -6
  170. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  171. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  172. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  173. package/dist/skills/ulw-research/SKILL.md +4 -2
  174. package/dist/skills/visual-qa/AGENTS.md +58 -0
  175. package/dist/skills/visual-qa/SKILL.md +3 -2
  176. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  177. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  178. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  179. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  180. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  181. package/dist/tools/delegate-task/types.d.ts +4 -0
  182. package/dist/tui.d.ts +12 -0
  183. package/dist/tui.js +11522 -11501
  184. package/package.json +42 -36
  185. package/packages/git-bash-mcp/dist/cli.js +6 -1
  186. package/packages/git-bash-mcp/package.json +1 -1
  187. package/packages/lsp-core/src/index.ts +1 -0
  188. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  189. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  190. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  191. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
  192. package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
  193. package/packages/lsp-core/src/lsp/client.ts +26 -0
  194. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  195. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  196. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  197. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  198. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  199. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  200. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  201. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  202. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  203. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  204. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  205. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  206. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  207. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  208. package/packages/lsp-core/src/lsp/transport.ts +9 -0
  209. package/packages/lsp-core/src/lsp/types.ts +8 -0
  210. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  211. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  212. package/packages/lsp-core/src/mcp.ts +3 -0
  213. package/packages/lsp-core/src/request-context.test.ts +29 -0
  214. package/packages/lsp-core/src/request-context.ts +1 -1
  215. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  216. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  217. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  218. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  219. package/packages/lsp-core/src/tools/format.ts +56 -0
  220. package/packages/lsp-core/src/tools/index.ts +1 -0
  221. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  222. package/packages/lsp-core/src/tools/rename.ts +4 -2
  223. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  224. package/packages/lsp-core/src/tools/types.ts +10 -0
  225. package/packages/lsp-daemon/dist/cli.js +752 -307
  226. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  227. package/packages/lsp-daemon/dist/client.js +712 -264
  228. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  229. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  230. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  231. package/packages/lsp-daemon/dist/index.js +716 -273
  232. package/packages/lsp-daemon/dist/proxy.js +3 -0
  233. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  234. package/packages/lsp-daemon/package.json +1 -1
  235. package/packages/lsp-tools-mcp/dist/cli.js +671 -228
  236. package/packages/lsp-tools-mcp/dist/lsp/manager.js +207 -103
  237. package/packages/lsp-tools-mcp/dist/mcp.js +673 -230
  238. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  239. package/packages/lsp-tools-mcp/dist/tools.js +677 -238
  240. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  241. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  242. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  243. package/packages/omo-codex/plugin/README.md +1 -1
  244. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
  245. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  246. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  247. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  248. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +323 -117
  249. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -85
  250. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  251. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  252. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
  253. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  254. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
  255. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  256. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  257. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  258. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  259. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  260. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  261. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  262. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  263. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  264. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  265. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  266. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  267. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  268. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  269. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  270. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  271. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  272. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  273. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  274. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  275. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  276. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  277. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +702 -278
  278. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  279. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  280. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  281. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  282. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  283. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  284. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  285. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  286. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  287. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  288. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  289. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  290. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  291. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  292. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  293. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  294. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  295. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  296. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  297. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  298. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  299. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  300. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  301. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  302. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  303. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  304. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  305. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  306. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  307. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  308. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  309. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  310. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  311. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  312. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  313. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  314. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  315. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  316. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  317. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  318. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  319. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  320. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  321. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  322. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  323. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  324. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  325. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  326. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  327. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  328. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  329. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  330. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  331. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  332. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  333. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  334. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  335. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  336. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  337. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  338. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  339. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  340. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  341. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  342. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  343. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  344. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  345. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  346. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  347. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  348. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  349. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  350. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  351. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  352. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  353. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  354. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  355. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  356. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  357. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  358. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  359. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  360. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +17 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  362. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  363. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +11 -1
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +124 -68
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +9 -6
  371. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  372. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  373. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  374. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +7 -10
  375. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
  376. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  377. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
  378. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
  379. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  380. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  381. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  382. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  383. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  384. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -0
  385. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
  386. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
  387. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  388. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
  389. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  390. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  391. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  392. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
  393. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
  394. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  395. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -0
  396. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  397. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +44 -1
  398. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  399. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  400. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +27 -2
  401. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  402. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  403. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  404. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  405. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  406. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +45 -2
  407. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
  408. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  409. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  410. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  411. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  412. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  413. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  414. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  415. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  416. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  417. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  418. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  419. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  420. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  421. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  422. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  423. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  424. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  425. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  426. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  427. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  428. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  429. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  430. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  432. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  433. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  434. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  435. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  436. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  437. package/packages/omo-codex/plugin/package-lock.json +681 -395
  438. package/packages/omo-codex/plugin/package.json +2 -2
  439. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  440. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  441. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  442. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  443. package/packages/omo-codex/plugin/shared/package.json +3 -4
  444. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  445. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  446. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  447. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  448. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  449. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  450. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  451. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  452. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  453. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  454. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  455. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  456. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  457. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  458. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  459. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  460. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  461. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  462. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  463. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  464. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  465. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  466. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  467. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  468. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  469. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  470. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  471. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  472. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  473. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  474. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  475. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  476. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  477. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  478. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  479. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  480. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  481. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  482. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  483. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  484. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  485. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  486. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  487. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  488. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  489. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  490. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  491. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  492. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  493. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  494. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  495. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  496. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  497. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  498. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  499. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  500. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  501. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  502. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  503. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  504. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  505. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  506. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  507. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
  508. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  509. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  510. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  511. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  512. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  513. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  514. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  515. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  516. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  517. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  518. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  519. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  520. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  521. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  522. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  523. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  524. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  525. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  526. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  527. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
  528. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  529. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  530. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  531. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  532. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  533. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  534. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  535. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  536. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  537. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  538. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  539. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  540. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  541. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  542. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  543. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  544. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  545. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  546. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  547. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  548. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  549. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  550. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  551. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  552. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  553. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  554. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  555. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  556. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  557. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  558. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  559. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  560. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  561. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  562. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  563. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  564. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  565. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  566. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  567. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  568. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  569. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  570. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  571. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  572. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  573. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  574. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  575. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  576. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  577. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  578. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  579. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  580. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  581. package/script/qa/xterm-live-terminal.mjs +18 -2
  582. package/dist/config/schema/start-work.d.ts +0 -5
  583. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  584. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  585. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  586. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  587. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  588. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  589. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  590. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  591. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  592. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  593. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  594. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  595. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  596. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  597. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  598. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  599. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  600. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  601. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  602. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  603. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  604. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  605. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  606. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  607. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  608. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  609. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  610. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  611. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  612. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  613. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  614. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  615. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  616. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  617. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  618. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  619. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  620. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  621. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  622. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  623. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  624. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  625. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  626. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  627. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  628. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  629. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  630. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  631. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  632. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  633. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  634. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  635. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  636. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  637. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  638. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  639. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  // ../lsp-core/src/lsp/client-wrapper.ts
2
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
3
- import { dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
2
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
3
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
4
4
 
5
5
  // ../lsp-core/src/request-context.ts
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -9,18 +9,17 @@ import { homedir } from "node:os";
9
9
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
10
10
 
11
11
  class LspRequestContextParseError extends Error {
12
- code;
13
- name = "LspRequestContextParseError";
14
12
  constructor(code, message) {
15
13
  super(message);
16
14
  this.code = code;
15
+ this.name = "LspRequestContextParseError";
17
16
  }
18
17
  }
19
18
 
20
19
  class LspRequestContextUnavailableError extends Error {
21
- name = "LspRequestContextUnavailableError";
22
20
  constructor() {
23
21
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
22
+ this.name = "LspRequestContextUnavailableError";
24
23
  }
25
24
  }
26
25
  var storage = new AsyncLocalStorage;
@@ -50,7 +49,7 @@ function contextEnv(key) {
50
49
  }
51
50
  function createStandaloneMcpRequestContext(input = {}) {
52
51
  const env = input.env ?? process.env;
53
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
52
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
54
53
  const home = input.homeDir ?? homedir();
55
54
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
56
55
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -193,22 +192,15 @@ function effectiveExtension(filePath) {
193
192
 
194
193
  // ../lsp-core/src/lsp/errors.ts
195
194
  class LspConnectionClosedError extends Error {
196
- serverId;
197
- root;
198
- name = "LspConnectionClosedError";
199
195
  constructor(serverId, root, message) {
200
196
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
201
197
  this.serverId = serverId;
202
198
  this.root = root;
199
+ this.name = "LspConnectionClosedError";
203
200
  }
204
201
  }
205
202
 
206
203
  class LspProcessExitedError extends Error {
207
- serverId;
208
- root;
209
- exitCode;
210
- stderrTail;
211
- name = "LspProcessExitedError";
212
204
  constructor(serverId, root, exitCode, stderrTail) {
213
205
  const stderrSuffix = stderrTail ? `
214
206
  stderr tail: ${stderrTail}` : "";
@@ -217,46 +209,59 @@ stderr tail: ${stderrTail}` : "";
217
209
  this.root = root;
218
210
  this.exitCode = exitCode;
219
211
  this.stderrTail = stderrTail;
212
+ this.name = "LspProcessExitedError";
220
213
  }
221
214
  }
222
215
 
223
216
  class LspRequestTimeoutError extends Error {
224
- method;
225
- stderrTail;
226
- name = "LspRequestTimeoutError";
227
217
  constructor(method, stderrTail) {
228
218
  const stderrSuffix = stderrTail ? `
229
219
  recent stderr: ${stderrTail}` : "";
230
220
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
231
221
  this.method = method;
232
222
  this.stderrTail = stderrTail;
223
+ this.name = "LspRequestTimeoutError";
233
224
  }
234
225
  }
235
226
 
236
227
  class LspInvalidPathError extends Error {
237
- name = "LspInvalidPathError";
228
+ constructor() {
229
+ super(...arguments);
230
+ this.name = "LspInvalidPathError";
231
+ }
238
232
  }
239
233
 
240
234
  class LspServerLookupError extends Error {
241
- lookup;
242
- name = "LspServerLookupError";
243
235
  constructor(message, lookup) {
244
236
  super(message);
245
237
  this.lookup = lookup;
238
+ this.name = "LspServerLookupError";
246
239
  }
247
240
  }
248
241
 
249
242
  class LspServerInitializingError extends Error {
250
- originalError;
251
- name = "LspServerInitializingError";
252
243
  constructor(originalError) {
253
244
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
254
245
  this.originalError = originalError;
246
+ this.name = "LspServerInitializingError";
255
247
  }
256
248
  }
257
249
 
258
250
  class LspProcessSpawnError extends Error {
259
- name = "LspProcessSpawnError";
251
+ constructor() {
252
+ super(...arguments);
253
+ this.name = "LspProcessSpawnError";
254
+ }
255
+ }
256
+
257
+ class LspClientRespawnBudgetExceededError extends Error {
258
+ constructor(serverId, root, retryLimit) {
259
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
260
+ this.serverId = serverId;
261
+ this.root = root;
262
+ this.retryLimit = retryLimit;
263
+ this.name = "LspClientRespawnBudgetExceededError";
264
+ }
260
265
  }
261
266
  function isLspDeadConnectionError(err) {
262
267
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -287,9 +292,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
287
292
  var REQUEST_TIMEOUT_MS = 15000;
288
293
  var INIT_TIMEOUT_MS = 60000;
289
294
  var IDLE_TIMEOUT_MS = 5 * 60000;
295
+ var MAX_RESIDENT_CLIENTS = 6;
290
296
  var REAPER_INTERVAL_MS = 60000;
291
297
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
292
298
  var STOP_SIGKILL_GRACE_MS = 1000;
299
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
300
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
293
301
 
294
302
  // ../lsp-core/src/lsp/json-rpc-connection.ts
295
303
  var HEADER_SEPARATOR = `\r
@@ -301,20 +309,31 @@ var METHOD_NOT_FOUND = -32601;
301
309
  var INTERNAL_ERROR = -32603;
302
310
 
303
311
  class JsonRpcConnection {
304
- reader;
305
- writer;
306
- pendingRequests = new Map;
307
- notificationHandlers = new Map;
308
- requestHandlers = new Map;
309
- closeHandlers = [];
310
- errorHandlers = [];
311
- inputBuffer = Buffer.alloc(0);
312
- nextRequestId = 1;
313
- listening = false;
314
- disposed = false;
315
312
  constructor(reader, writer) {
316
313
  this.reader = reader;
317
314
  this.writer = writer;
315
+ this.pendingRequests = new Map;
316
+ this.notificationHandlers = new Map;
317
+ this.requestHandlers = new Map;
318
+ this.closeHandlers = [];
319
+ this.errorHandlers = [];
320
+ this.inputBuffer = Buffer.alloc(0);
321
+ this.nextRequestId = 1;
322
+ this.listening = false;
323
+ this.disposed = false;
324
+ this.handleData = (chunk) => {
325
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
326
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
327
+ this.drainInputBuffer();
328
+ };
329
+ this.handleClose = () => {
330
+ for (const handler of this.closeHandlers) {
331
+ handler();
332
+ }
333
+ };
334
+ this.handleStreamError = (error) => {
335
+ this.emitError(error);
336
+ };
318
337
  }
319
338
  listen() {
320
339
  if (this.listening)
@@ -435,19 +454,6 @@ class JsonRpcConnection {
435
454
  this.notificationHandlers.clear();
436
455
  this.requestHandlers.clear();
437
456
  }
438
- handleData = (chunk) => {
439
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
440
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
441
- this.drainInputBuffer();
442
- };
443
- handleClose = () => {
444
- for (const handler of this.closeHandlers) {
445
- handler();
446
- }
447
- };
448
- handleStreamError = (error) => {
449
- this.emitError(error);
450
- };
451
457
  drainInputBuffer() {
452
458
  while (true) {
453
459
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -795,31 +801,26 @@ function isPosition(value) {
795
801
 
796
802
  // ../lsp-core/src/lsp/transport.ts
797
803
  class LspClientNotStartedError extends Error {
798
- serverId;
799
- root;
800
- name = "LspClientNotStartedError";
801
804
  constructor(serverId, root) {
802
805
  super("LSP client not started");
803
806
  this.serverId = serverId;
804
807
  this.root = root;
808
+ this.name = "LspClientNotStartedError";
805
809
  }
806
810
  }
807
811
 
808
812
  class LspClientTransport {
809
- root;
810
- server;
811
- proc = null;
812
- connection = null;
813
- stderrBuffer = [];
814
- processExited = false;
815
- diagnosticsStore = new Map;
816
- requestTimeoutMs;
817
- initializeTimeoutMs;
818
- workspaceApplyEditHandler = null;
819
- diagnosticPullSupported = false;
820
813
  constructor(root, server, timeouts = {}) {
821
814
  this.root = root;
822
815
  this.server = server;
816
+ this.proc = null;
817
+ this.connection = null;
818
+ this.stderrBuffer = [];
819
+ this.processExited = false;
820
+ this.diagnosticsStore = new Map;
821
+ this.workspaceApplyEditHandler = null;
822
+ this.diagnosticPullSupported = false;
823
+ this.documentFormattingSupported = false;
823
824
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
824
825
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
825
826
  }
@@ -841,6 +842,12 @@ class LspClientTransport {
841
842
  isDiagnosticPullSupported() {
842
843
  return this.diagnosticPullSupported;
843
844
  }
845
+ setDocumentFormattingSupported(supported) {
846
+ this.documentFormattingSupported = supported;
847
+ }
848
+ isDocumentFormattingSupported() {
849
+ return this.documentFormattingSupported;
850
+ }
844
851
  handlePublishDiagnostics(params) {
845
852
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
846
853
  }
@@ -1054,6 +1061,14 @@ function supportsDiagnosticPull(capabilities) {
1054
1061
  return false;
1055
1062
  return Object.hasOwn(capabilities, "diagnosticProvider");
1056
1063
  }
1064
+ function supportsDocumentFormatting(capabilities) {
1065
+ if (capabilities === undefined)
1066
+ return false;
1067
+ const provider = capabilities.documentFormattingProvider;
1068
+ if (provider === undefined || provider === null || provider === false)
1069
+ return false;
1070
+ return provider === true || typeof provider === "object";
1071
+ }
1057
1072
 
1058
1073
  class LspClientConnection extends LspClientTransport {
1059
1074
  async initialize() {
@@ -1070,6 +1085,7 @@ class LspClientConnection extends LspClientTransport {
1070
1085
  references: {},
1071
1086
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1072
1087
  publishDiagnostics: {},
1088
+ formatting: { dynamicRegistration: false },
1073
1089
  rename: {
1074
1090
  prepareSupport: true,
1075
1091
  prepareSupportDefaultBehavior: 1
@@ -1111,6 +1127,7 @@ class LspClientConnection extends LspClientTransport {
1111
1127
  initializationOptions: this.server.initialization
1112
1128
  }, { timeoutMs: this.initializeTimeoutMs });
1113
1129
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1130
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1114
1131
  await this.sendNotification("initialized", {});
1115
1132
  await this.sendNotification("workspace/didChangeConfiguration", {
1116
1133
  settings: { json: { validate: { enable: true } } }
@@ -1316,16 +1333,12 @@ function movedPath(candidate, oldPath, newPath) {
1316
1333
  }
1317
1334
 
1318
1335
  class WorkspaceDocumentState {
1319
- sendNotification;
1320
- clearDiagnostics;
1321
- openDocuments = new Map;
1322
- openByUri = new Map;
1323
- openPromises = new Map;
1324
- now;
1325
- versionlessPublishQuiescenceMs;
1326
1336
  constructor(sendNotification, clearDiagnostics, options = {}) {
1327
1337
  this.sendNotification = sendNotification;
1328
1338
  this.clearDiagnostics = clearDiagnostics;
1339
+ this.openDocuments = new Map;
1340
+ this.openByUri = new Map;
1341
+ this.openPromises = new Map;
1329
1342
  this.now = options.now ?? (() => Date.now());
1330
1343
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1331
1344
  }
@@ -1589,13 +1602,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
1589
1602
  import { fileURLToPath } from "node:url";
1590
1603
 
1591
1604
  class WorkspaceEditPathError extends Error {
1592
- path;
1593
- detail;
1594
- name = "WorkspaceEditPathError";
1595
1605
  constructor(path, detail) {
1596
1606
  super(`${detail}: ${path}`);
1597
1607
  this.path = path;
1598
1608
  this.detail = detail;
1609
+ this.name = "WorkspaceEditPathError";
1599
1610
  }
1600
1611
  }
1601
1612
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1887,13 +1898,11 @@ function canonicalFingerprint(operations) {
1887
1898
 
1888
1899
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1889
1900
  class WorkspaceEditValidationError extends Error {
1890
- changeIndex;
1891
- detail;
1892
- name = "WorkspaceEditValidationError";
1893
1901
  constructor(changeIndex, detail) {
1894
1902
  super(`change ${changeIndex}: ${detail}`);
1895
1903
  this.changeIndex = changeIndex;
1896
1904
  this.detail = detail;
1905
+ this.name = "WorkspaceEditValidationError";
1897
1906
  }
1898
1907
  }
1899
1908
 
@@ -2391,10 +2400,9 @@ function simulateDelete(operation, virtual) {
2391
2400
  import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2392
2401
  import { dirname as dirname4, resolve as resolve5 } from "node:path";
2393
2402
  class WorkspaceSnapshotBuilder {
2394
- workspaceRoot;
2395
- snapshots = new Map;
2396
2403
  constructor(workspaceRoot) {
2397
2404
  this.workspaceRoot = workspaceRoot;
2405
+ this.snapshots = new Map;
2398
2406
  }
2399
2407
  build(operations) {
2400
2408
  this.add(this.workspaceRoot, false);
@@ -2438,8 +2446,10 @@ function snapshotOperations(operations, workspaceRoot) {
2438
2446
 
2439
2447
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2440
2448
  class PlanPathIndex {
2441
- firstChangeByPath = new Map;
2442
- reportedPathByCanonical = new Map;
2449
+ constructor() {
2450
+ this.firstChangeByPath = new Map;
2451
+ this.reportedPathByCanonical = new Map;
2452
+ }
2443
2453
  build(operations) {
2444
2454
  for (const operation of operations) {
2445
2455
  switch (operation.kind) {
@@ -2528,14 +2538,11 @@ function isRecord4(value) {
2528
2538
  }
2529
2539
 
2530
2540
  class WorkspaceMutationController {
2531
- workspaceRoot;
2532
- documents;
2533
- activeLease = null;
2534
- nextLeaseId = 1;
2535
- io;
2536
2541
  constructor(workspaceRoot, documents) {
2537
2542
  this.workspaceRoot = workspaceRoot;
2538
2543
  this.documents = documents;
2544
+ this.activeLease = null;
2545
+ this.nextLeaseId = 1;
2539
2546
  }
2540
2547
  setIo(io) {
2541
2548
  this.io = io;
@@ -2648,12 +2655,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2648
2655
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2649
2656
 
2650
2657
  class LspClient extends LspClientConnection {
2651
- diagnosticPullErrors = [];
2652
- documents;
2653
- workspaceMutations;
2654
- diagnosticsFreshnessTimeoutMs;
2655
2658
  constructor(root, server, options = {}) {
2656
2659
  super(root, server, options);
2660
+ this.diagnosticPullErrors = [];
2657
2661
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2658
2662
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2659
2663
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
@@ -2708,6 +2712,18 @@ class LspClient extends LspClientConnection {
2708
2712
  textDocument: { uri: pathToFileURL3(absPath).href }
2709
2713
  }, options);
2710
2714
  }
2715
+ async formatDocument(filePath, options, signal) {
2716
+ if (!this.isDocumentFormattingSupported())
2717
+ return null;
2718
+ const absPath = this.resolveWorkspacePath(filePath);
2719
+ await this.openFile(absPath);
2720
+ const requestOptions = signal === undefined ? {} : { signal };
2721
+ const edits = await this.sendRequest("textDocument/formatting", {
2722
+ textDocument: { uri: pathToFileURL3(absPath).href },
2723
+ options
2724
+ }, requestOptions);
2725
+ return edits ?? [];
2726
+ }
2711
2727
  async workspaceSymbols(query, signal) {
2712
2728
  const options = signal === undefined ? {} : { signal };
2713
2729
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2953,18 +2969,16 @@ function awaitWithSignal(promise, signal) {
2953
2969
  }
2954
2970
 
2955
2971
  class LspManager {
2956
- clients = new Map;
2957
- reaperHandle = null;
2958
- signalDisposer = null;
2959
- disposed = false;
2960
- idleTimeoutMs;
2961
- initTimeoutMs;
2962
- reaperIntervalMs;
2963
- clientFactory;
2964
- now;
2965
2972
  constructor(options = {}) {
2973
+ this.clients = new Map;
2974
+ this.pendingStops = new Map;
2975
+ this.respawnBudgets = new Map;
2976
+ this.reaperHandle = null;
2977
+ this.signalDisposer = null;
2978
+ this.disposed = false;
2966
2979
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2967
2980
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2981
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2968
2982
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2969
2983
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2970
2984
  this.now = options.now ?? (() => Date.now());
@@ -2984,24 +2998,79 @@ class LspManager {
2984
2998
  getKey(root, serverId) {
2985
2999
  return `${root}::${serverId}`;
2986
3000
  }
3001
+ tombstoneStop(key, client) {
3002
+ const stop = stopClientBestEffort(client);
3003
+ this.pendingStops.set(key, stop);
3004
+ stop.finally(() => {
3005
+ if (this.pendingStops.get(key) === stop) {
3006
+ this.pendingStops.delete(key);
3007
+ }
3008
+ });
3009
+ return stop;
3010
+ }
3011
+ recordDeadGeneration(key) {
3012
+ let budget = this.respawnBudgets.get(key);
3013
+ if (budget === undefined) {
3014
+ budget = { deadGenerations: 0, exhaustedAt: null };
3015
+ this.respawnBudgets.set(key, budget);
3016
+ }
3017
+ budget.deadGenerations += 1;
3018
+ }
3019
+ markHealthyGeneration(key) {
3020
+ this.respawnBudgets.delete(key);
3021
+ }
3022
+ ensureRespawnAllowed(key, root, serverId) {
3023
+ const budget = this.respawnBudgets.get(key);
3024
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3025
+ return;
3026
+ if (budget.exhaustedAt === null) {
3027
+ budget.exhaustedAt = this.now();
3028
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3029
+ }
3030
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3031
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3032
+ }
3033
+ budget.deadGenerations = 0;
3034
+ budget.exhaustedAt = null;
3035
+ }
2987
3036
  reapStale() {
2988
3037
  const t = this.now();
2989
3038
  for (const [key, managed] of this.clients) {
2990
3039
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2991
- stopClientBestEffort(managed.client);
2992
3040
  this.clients.delete(key);
3041
+ this.tombstoneStop(key, managed.client);
2993
3042
  continue;
2994
3043
  }
2995
3044
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
2996
- stopClientBestEffort(managed.client);
2997
3045
  this.clients.delete(key);
3046
+ this.tombstoneStop(key, managed.client);
3047
+ }
3048
+ }
3049
+ }
3050
+ evictForAdmission() {
3051
+ while (this.clients.size >= this.maxResidentClients) {
3052
+ const victim = this.leastRecentlyUsedIdleClient();
3053
+ if (!victim)
3054
+ return;
3055
+ this.clients.delete(victim.key);
3056
+ this.tombstoneStop(victim.key, victim.managed.client);
3057
+ }
3058
+ }
3059
+ leastRecentlyUsedIdleClient() {
3060
+ let candidate = null;
3061
+ for (const [key, managed] of this.clients) {
3062
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3063
+ continue;
3064
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3065
+ candidate = { key, managed };
2998
3066
  }
2999
3067
  }
3068
+ return candidate;
3000
3069
  }
3001
3070
  async tryDeleteIfOrphaned(key, managed) {
3002
3071
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3003
3072
  this.clients.delete(key);
3004
- await stopClientBestEffort(managed.client);
3073
+ await this.tombstoneStop(key, managed.client);
3005
3074
  }
3006
3075
  }
3007
3076
  async getClient(root, server, signal) {
@@ -3010,12 +3079,22 @@ class LspManager {
3010
3079
  }
3011
3080
  signal?.throwIfAborted();
3012
3081
  const key = this.getKey(root, server.id);
3082
+ for (;; ) {
3083
+ const pendingStop = this.pendingStops.get(key);
3084
+ if (pendingStop === undefined)
3085
+ break;
3086
+ await awaitWithSignal(pendingStop, signal);
3087
+ signal?.throwIfAborted();
3088
+ }
3089
+ if (this.disposed) {
3090
+ throw new Error("LspManager has been disposed");
3091
+ }
3013
3092
  let managed = this.clients.get(key);
3014
3093
  if (managed) {
3015
3094
  const t = this.now();
3016
3095
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3017
- await stopClientBestEffort(managed.client);
3018
3096
  this.clients.delete(key);
3097
+ await this.tombstoneStop(key, managed.client);
3019
3098
  managed = undefined;
3020
3099
  }
3021
3100
  }
@@ -3036,14 +3115,20 @@ class LspManager {
3036
3115
  signal.throwIfAborted();
3037
3116
  }
3038
3117
  if (!managed.client.isAlive()) {
3039
- await stopClientBestEffort(managed.client);
3040
- this.clients.delete(key);
3118
+ this.recordDeadGeneration(key);
3119
+ if (this.clients.get(key) === managed) {
3120
+ this.clients.delete(key);
3121
+ }
3122
+ await this.tombstoneStop(key, managed.client);
3041
3123
  return this.getClient(root, server, signal);
3042
3124
  }
3125
+ this.markHealthyGeneration(key);
3043
3126
  managed.refCount++;
3044
3127
  managed.lastUsedAt = this.now();
3045
3128
  return managed.client;
3046
3129
  }
3130
+ this.evictForAdmission();
3131
+ this.ensureRespawnAllowed(key, root, server.id);
3047
3132
  const client = this.clientFactory(root, server);
3048
3133
  const initStartedAt = this.now();
3049
3134
  const initPromise = (async () => {
@@ -3067,7 +3152,7 @@ class LspManager {
3067
3152
  if (this.clients.get(key) === newManaged) {
3068
3153
  this.clients.delete(key);
3069
3154
  }
3070
- await stopClientBestEffort(client);
3155
+ await this.tombstoneStop(key, client);
3071
3156
  throw err;
3072
3157
  }
3073
3158
  newManaged.pendingWaiters--;
@@ -3078,6 +3163,15 @@ class LspManager {
3078
3163
  await this.tryDeleteIfOrphaned(key, newManaged);
3079
3164
  signal.throwIfAborted();
3080
3165
  }
3166
+ if (!client.isAlive()) {
3167
+ this.recordDeadGeneration(key);
3168
+ if (this.clients.get(key) === newManaged) {
3169
+ this.clients.delete(key);
3170
+ }
3171
+ await this.tombstoneStop(key, client);
3172
+ return this.getClient(root, server, signal);
3173
+ }
3174
+ this.markHealthyGeneration(key);
3081
3175
  newManaged.refCount++;
3082
3176
  newManaged.lastUsedAt = this.now();
3083
3177
  return client;
@@ -3098,14 +3192,20 @@ class LspManager {
3098
3192
  if (client && managed.client !== client)
3099
3193
  return;
3100
3194
  this.clients.delete(key);
3101
- stopClientBestEffort(managed.client);
3195
+ this.tombstoneStop(key, managed.client);
3102
3196
  }
3103
3197
  warmupClient(root, server) {
3104
3198
  if (this.disposed)
3105
3199
  return;
3106
3200
  const key = this.getKey(root, server.id);
3107
- if (this.clients.has(key))
3201
+ if (this.clients.has(key) || this.pendingStops.has(key))
3108
3202
  return;
3203
+ this.evictForAdmission();
3204
+ try {
3205
+ this.ensureRespawnAllowed(key, root, server.id);
3206
+ } catch {
3207
+ return;
3208
+ }
3109
3209
  const client = this.clientFactory(root, server);
3110
3210
  const initStartedAt = this.now();
3111
3211
  const initPromise = (async () => {
@@ -3131,7 +3231,7 @@ class LspManager {
3131
3231
  if (this.clients.get(key) === managed) {
3132
3232
  this.clients.delete(key);
3133
3233
  }
3134
- stopClientBestEffort(client);
3234
+ this.tombstoneStop(key, client);
3135
3235
  });
3136
3236
  }
3137
3237
  isServerInitializing(root, serverId) {
@@ -3175,8 +3275,11 @@ class LspManager {
3175
3275
  for (const managed of this.clients.values()) {
3176
3276
  stopPromises.push(stopClientBestEffort(managed.client));
3177
3277
  }
3278
+ const tombstonedStops = [...this.pendingStops.values()];
3178
3279
  this.clients.clear();
3179
- await Promise.allSettled(stopPromises);
3280
+ this.respawnBudgets.clear();
3281
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3282
+ this.pendingStops.clear();
3180
3283
  }
3181
3284
  }
3182
3285
  var _defaultInstance = null;
@@ -3194,57 +3297,52 @@ async function disposeDefaultLspManager() {
3194
3297
  }
3195
3298
  }
3196
3299
 
3197
- // ../lsp-core/src/lsp/server-install-state.ts
3198
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3199
- import { dirname as dirname5 } from "node:path";
3200
- function getInstallDecisionsPath() {
3201
- return lspRequestContext().installDecisionsPath;
3202
- }
3203
- function loadInstallDecisions() {
3204
- const path = getInstallDecisionsPath();
3205
- if (!existsSync6(path))
3206
- return {};
3207
- try {
3208
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3209
- return isInstallDecisions(parsed) ? parsed : {};
3210
- } catch {
3211
- return {};
3300
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3301
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3302
+ import { dirname as dirname5, join as join3 } from "node:path";
3303
+
3304
+ // ../lsp-core/src/lsp/workspace-markers.ts
3305
+ var GIT_WORKSPACE_MARKER = ".git";
3306
+ var PROJECT_WORKSPACE_MARKERS = [
3307
+ "package.json",
3308
+ "pyproject.toml",
3309
+ "Cargo.toml",
3310
+ "go.mod",
3311
+ "pom.xml",
3312
+ "build.gradle"
3313
+ ];
3314
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3315
+
3316
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3317
+ function findWorkspaceRootOutsideContext(directory) {
3318
+ const marked = nearestMarkedAncestor(directory);
3319
+ if (marked !== undefined)
3320
+ return marked;
3321
+ return realpathSync4(nearestExistingAncestor(directory));
3322
+ }
3323
+ function nearestMarkedAncestor(directory) {
3324
+ let current = directory;
3325
+ for (;; ) {
3326
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3327
+ return realpathSync4(current);
3328
+ }
3329
+ const parent = dirname5(current);
3330
+ if (parent === current)
3331
+ return;
3332
+ current = parent;
3212
3333
  }
3213
3334
  }
3214
- function loadInstallDecision(serverId) {
3215
- return loadInstallDecisions()[serverId];
3216
- }
3217
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3218
- const decisions = loadInstallDecisions();
3219
- decisions[serverId] = { decision, decidedAt };
3220
- writeInstallDecisions(decisions);
3221
- }
3222
- function isInstallDecision(value) {
3223
- return value === "declined" || value === "allowed";
3224
- }
3225
- function writeInstallDecisions(decisions) {
3226
- const path = getInstallDecisionsPath();
3227
- mkdirSync(dirname5(path), { recursive: true });
3228
- const tmpPath = `${path}.tmp`;
3229
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3230
- `, "utf8");
3231
- renameSync2(tmpPath, path);
3232
- }
3233
- function isInstallDecisions(value) {
3234
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3235
- }
3236
- function isInstallDecisionRecord(value) {
3237
- if (!isRecord5(value))
3238
- return false;
3239
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3240
- }
3241
- function isRecord5(value) {
3242
- return typeof value === "object" && value !== null && !Array.isArray(value);
3335
+ function nearestExistingAncestor(directory) {
3336
+ let current = directory;
3337
+ while (!existsSync6(current)) {
3338
+ const parent = dirname5(current);
3339
+ if (parent === current)
3340
+ return current;
3341
+ current = parent;
3342
+ }
3343
+ return current;
3243
3344
  }
3244
3345
 
3245
- // ../lsp-core/src/lsp/config-loader.ts
3246
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3247
-
3248
3346
  // ../lsp-core/src/lsp/server-definitions.ts
3249
3347
  var LSP_INSTALL_HINTS = {
3250
3348
  typescript: "npm install -g typescript-language-server typescript",
@@ -3290,6 +3388,26 @@ var LSP_INSTALL_HINTS = {
3290
3388
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3291
3389
  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"
3292
3390
  };
3391
+ var LSP_LOCAL_INSTALL_HINTS = {
3392
+ typescript: "bun add -d typescript-language-server typescript",
3393
+ vue: "bun add -d @vue/language-server",
3394
+ eslint: "bun add -d vscode-langservers-extracted",
3395
+ oxlint: "bun add -d oxlint",
3396
+ biome: "bun add -d @biomejs/biome",
3397
+ svelte: "bun add -d svelte-language-server",
3398
+ astro: "bun add -d @astrojs/language-server",
3399
+ bash: "bun add -d bash-language-server",
3400
+ "bash-ls": "bun add -d bash-language-server",
3401
+ "yaml-ls": "bun add -d yaml-language-server",
3402
+ php: "bun add -d intelephense",
3403
+ prisma: "bun add -d prisma",
3404
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3405
+ pyright: "uv add --dev pyright",
3406
+ basedpyright: "uv add --dev basedpyright",
3407
+ ruff: "uv add --dev ruff",
3408
+ ty: "uv add --dev ty",
3409
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3410
+ };
3293
3411
  var BUILTIN_SERVERS = {
3294
3412
  typescript: {
3295
3413
  command: ["typescript-language-server", "--stdio"],
@@ -3392,7 +3510,56 @@ var BUILTIN_SERVERS = {
3392
3510
  }
3393
3511
  };
3394
3512
 
3513
+ // ../lsp-core/src/lsp/server-install-state.ts
3514
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3515
+ import { dirname as dirname6 } from "node:path";
3516
+ function getInstallDecisionsPath() {
3517
+ return lspRequestContext().installDecisionsPath;
3518
+ }
3519
+ function loadInstallDecisions() {
3520
+ const path = getInstallDecisionsPath();
3521
+ if (!existsSync7(path))
3522
+ return {};
3523
+ try {
3524
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3525
+ return isInstallDecisions(parsed) ? parsed : {};
3526
+ } catch {
3527
+ return {};
3528
+ }
3529
+ }
3530
+ function loadInstallDecision(serverId) {
3531
+ return loadInstallDecisions()[serverId];
3532
+ }
3533
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3534
+ const decisions = loadInstallDecisions();
3535
+ decisions[serverId] = { decision, decidedAt };
3536
+ writeInstallDecisions(decisions);
3537
+ }
3538
+ function isInstallDecision(value) {
3539
+ return value === "declined" || value === "allowed";
3540
+ }
3541
+ function writeInstallDecisions(decisions) {
3542
+ const path = getInstallDecisionsPath();
3543
+ mkdirSync(dirname6(path), { recursive: true });
3544
+ const tmpPath = `${path}.tmp`;
3545
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3546
+ `, "utf8");
3547
+ renameSync2(tmpPath, path);
3548
+ }
3549
+ function isInstallDecisions(value) {
3550
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3551
+ }
3552
+ function isInstallDecisionRecord(value) {
3553
+ if (!isRecord5(value))
3554
+ return false;
3555
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3556
+ }
3557
+ function isRecord5(value) {
3558
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3559
+ }
3560
+
3395
3561
  // ../lsp-core/src/lsp/config-loader.ts
3562
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3396
3563
  function getProjectConfigPaths() {
3397
3564
  return lspRequestContext().projectConfigPaths;
3398
3565
  }
@@ -3400,7 +3567,7 @@ function getUserConfigPath() {
3400
3567
  return lspRequestContext().userConfigPath;
3401
3568
  }
3402
3569
  function loadJsonFile(path) {
3403
- if (!existsSync7(path))
3570
+ if (!existsSync8(path))
3404
3571
  return null;
3405
3572
  try {
3406
3573
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3588,54 +3755,155 @@ function getDisabledServerIds() {
3588
3755
  }
3589
3756
 
3590
3757
  // ../lsp-core/src/lsp/server-installation.ts
3591
- import { existsSync as existsSync8 } from "node:fs";
3592
- import { delimiter as delimiter3, join as join3 } from "node:path";
3593
- function isServerInstalled(command, _workingDirectory) {
3594
- if (command.length === 0)
3595
- return false;
3596
- const [cmd] = command;
3597
- if (!cmd)
3598
- return false;
3599
- if (cmd.includes("/") || cmd.includes("\\")) {
3600
- if (existsSync8(cmd))
3601
- return true;
3758
+ import { existsSync as existsSync9 } from "node:fs";
3759
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
3760
+ var LOCAL_BIN_RULES = [
3761
+ {
3762
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
3763
+ binDirs: [join4("node_modules", ".bin")]
3764
+ },
3765
+ {
3766
+ markers: [
3767
+ "pyproject.toml",
3768
+ "ty.toml",
3769
+ "requirements.txt",
3770
+ "setup.py",
3771
+ "setup.cfg",
3772
+ "Pipfile",
3773
+ "pyrightconfig.json",
3774
+ "ruff.toml",
3775
+ ".ruff.toml"
3776
+ ],
3777
+ binDirs: [
3778
+ join4(".venv", "bin"),
3779
+ join4(".venv", "Scripts"),
3780
+ join4("venv", "bin"),
3781
+ join4("venv", "Scripts"),
3782
+ join4(".env", "bin"),
3783
+ join4(".env", "Scripts")
3784
+ ]
3785
+ },
3786
+ {
3787
+ markers: ["Gemfile", "Gemfile.lock"],
3788
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
3789
+ },
3790
+ {
3791
+ markers: ["go.mod", "go.sum", "go.work"],
3792
+ binDirs: ["bin"]
3602
3793
  }
3603
- const isWindows = process.platform === "win32";
3604
- let exts = [""];
3605
- if (isWindows) {
3606
- const pathExt = process.env["PATHEXT"] ?? "";
3607
- if (pathExt) {
3608
- const systemExts = pathExt.split(";").filter(Boolean);
3609
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3610
- } else {
3611
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
3794
+ ];
3795
+ var resolutionCache = new Map;
3796
+ var probeCount = 0;
3797
+ function probe(path) {
3798
+ probeCount += 1;
3799
+ return existsSync9(path);
3800
+ }
3801
+ function executableSuffixes(platform, pathExt) {
3802
+ if (platform !== "win32")
3803
+ return [""];
3804
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
3805
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
3806
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3807
+ }
3808
+ function probeWithSuffixes(directory, command, suffixes) {
3809
+ for (const suffix of suffixes) {
3810
+ const candidate = join4(directory, command + suffix);
3811
+ if (probe(candidate))
3812
+ return candidate;
3813
+ }
3814
+ return null;
3815
+ }
3816
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
3817
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
3818
+ let current = resolve7(workingDirectory);
3819
+ while (true) {
3820
+ for (const rule of LOCAL_BIN_RULES) {
3821
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
3822
+ continue;
3823
+ for (const binDir of rule.binDirs) {
3824
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
3825
+ if (found !== null)
3826
+ return found;
3827
+ }
3612
3828
  }
3829
+ if (probe(join4(current, ".git")))
3830
+ return null;
3831
+ if (boundary !== undefined && current === boundary)
3832
+ return null;
3833
+ const parent = dirname7(current);
3834
+ if (parent === current)
3835
+ return null;
3836
+ current = parent;
3613
3837
  }
3614
- let pathEnv = process.env["PATH"] ?? "";
3615
- if (isWindows && !pathEnv) {
3838
+ }
3839
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
3840
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
3841
+ if (platform === "win32" && !pathEnv) {
3616
3842
  pathEnv = process.env["Path"] ?? "";
3617
3843
  }
3618
- const paths = pathEnv.split(delimiter3);
3619
- for (const p of paths) {
3620
- for (const suffix of exts) {
3621
- if (existsSync8(join3(p, cmd + suffix))) {
3622
- return true;
3623
- }
3624
- }
3844
+ for (const entry of pathEnv.split(delimiter3)) {
3845
+ if (entry.length === 0)
3846
+ continue;
3847
+ const found = probeWithSuffixes(entry, command, suffixes);
3848
+ if (found !== null)
3849
+ return found;
3625
3850
  }
3626
- if (cmd === "node")
3627
- return true;
3628
- return false;
3851
+ return null;
3852
+ }
3853
+ function resolveServerBinary(command, workingDirectory, options = {}) {
3854
+ if (command.length === 0)
3855
+ return null;
3856
+ const [cmd] = command;
3857
+ if (cmd === undefined || cmd.length === 0)
3858
+ return null;
3859
+ const platform = options.platform ?? process.platform;
3860
+ const suffixes = executableSuffixes(platform, options.pathExt);
3861
+ if (cmd.includes("/") || cmd.includes("\\")) {
3862
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
3863
+ return probe(explicit) ? explicit : null;
3864
+ }
3865
+ const cacheKey = JSON.stringify([
3866
+ workingDirectory ?? "",
3867
+ cmd,
3868
+ platform,
3869
+ options.stopAt ?? "",
3870
+ options.pathExt ?? "",
3871
+ options.pathEnv ?? process.env["PATH"] ?? ""
3872
+ ]);
3873
+ const cached = resolutionCache.get(cacheKey);
3874
+ if (cached !== undefined)
3875
+ return cached;
3876
+ let resolved = null;
3877
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
3878
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
3879
+ }
3880
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
3881
+ if (resolved === null && cmd === "node")
3882
+ resolved = cmd;
3883
+ resolutionCache.set(cacheKey, resolved);
3884
+ return resolved;
3885
+ }
3886
+ function isServerInstalled(command, workingDirectory, options = {}) {
3887
+ if (command.length === 0)
3888
+ return false;
3889
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3629
3890
  }
3630
3891
 
3631
3892
  // ../lsp-core/src/lsp/server-resolution.ts
3893
+ function withResolvedCommand(command, binaryPath) {
3894
+ return [binaryPath, ...command.slice(1)];
3895
+ }
3632
3896
  function findServerForExtension(ext) {
3633
3897
  const servers = getMergedServers();
3898
+ const workingDirectory = contextCwd();
3634
3899
  for (const server of servers) {
3635
- if (server.extensions.includes(ext) && isServerInstalled(server.command)) {
3900
+ if (!server.extensions.includes(ext))
3901
+ continue;
3902
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
3903
+ if (binaryPath !== null) {
3636
3904
  const resolvedServer = {
3637
3905
  id: server.id,
3638
- command: server.command,
3906
+ command: withResolvedCommand(server.command, binaryPath),
3639
3907
  extensions: server.extensions,
3640
3908
  priority: server.priority
3641
3909
  };
@@ -3682,6 +3950,7 @@ function findServerForExtension(ext) {
3682
3950
  function getAllServers() {
3683
3951
  const servers = getMergedServers();
3684
3952
  const disabled = getDisabledServerIds();
3953
+ const workingDirectory = contextCwd();
3685
3954
  const result = [];
3686
3955
  const seen = new Set;
3687
3956
  for (const server of servers) {
@@ -3689,7 +3958,7 @@ function getAllServers() {
3689
3958
  continue;
3690
3959
  result.push({
3691
3960
  id: server.id,
3692
- installed: isServerInstalled(server.command),
3961
+ installed: isServerInstalled(server.command, workingDirectory),
3693
3962
  extensions: server.extensions,
3694
3963
  disabled: false,
3695
3964
  source: server.source,
@@ -3703,7 +3972,7 @@ function getAllServers() {
3703
3972
  const builtin = BUILTIN_SERVERS[id];
3704
3973
  result.push({
3705
3974
  id,
3706
- installed: builtin ? isServerInstalled(builtin.command) : false,
3975
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
3707
3976
  extensions: builtin?.extensions ?? [],
3708
3977
  disabled: true,
3709
3978
  source: "disabled",
@@ -3714,7 +3983,6 @@ function getAllServers() {
3714
3983
  }
3715
3984
 
3716
3985
  // ../lsp-core/src/lsp/client-wrapper.ts
3717
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
3718
3986
  function isDirectoryPath(filePath) {
3719
3987
  try {
3720
3988
  return statSync3(filePath).isDirectory();
@@ -3723,32 +3991,90 @@ function isDirectoryPath(filePath) {
3723
3991
  }
3724
3992
  }
3725
3993
  function findWorkspaceRoot(filePath) {
3726
- const abs = resolvePathInsideContext(filePath);
3994
+ const cwd = contextCwd();
3995
+ const abs = resolveReadablePathInsideContext(filePath);
3727
3996
  let dir = abs;
3728
3997
  if (!isDirectoryPath(dir)) {
3729
- dir = dirname6(dir);
3730
- }
3731
- let prevDir = "";
3732
- while (dir !== prevDir) {
3733
- for (const marker of WORKSPACE_MARKERS) {
3734
- if (existsSync9(join4(dir, marker))) {
3735
- return dir;
3998
+ dir = dirname8(dir);
3999
+ }
4000
+ if (!isPathInside(cwd, abs))
4001
+ return findWorkspaceRootOutsideContext(dir);
4002
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4003
+ let nearestPackageRoot;
4004
+ while (isPathInside(cwd, dir)) {
4005
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4006
+ if (canonicalDir !== undefined) {
4007
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4008
+ return canonicalDir;
4009
+ }
4010
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4011
+ nearestPackageRoot = canonicalDir;
3736
4012
  }
3737
4013
  }
3738
- prevDir = dir;
3739
- dir = dirname6(dir);
4014
+ if (dir === cwd)
4015
+ break;
4016
+ dir = dirname8(dir);
3740
4017
  }
3741
- return dirname6(abs);
4018
+ return nearestPackageRoot ?? fallbackRoot;
4019
+ }
4020
+ function hasProjectWorkspaceMarker(directory) {
4021
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4022
+ }
4023
+ function resolveReadablePathInsideContext(filePath) {
4024
+ const cwd = contextCwd();
4025
+ const abs = resolve8(cwd, filePath);
4026
+ if (isPathInside(cwd, abs))
4027
+ return abs;
4028
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4029
+ if (rebased !== undefined)
4030
+ return rebased;
4031
+ return canonicalizeExistingOrNearestAncestor(abs);
3742
4032
  }
3743
4033
  function resolvePathInsideContext(filePath) {
3744
4034
  const cwd = contextCwd();
3745
- const abs = resolve7(cwd, filePath);
4035
+ const abs = resolveReadablePathInsideContext(filePath);
3746
4036
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
3747
4037
  if (!isPathInside(cwd, canonical)) {
3748
4038
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
3749
4039
  }
3750
4040
  return canonical;
3751
4041
  }
4042
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4043
+ let current = path;
4044
+ const suffix = [];
4045
+ while (true) {
4046
+ if (existsSync10(current)) {
4047
+ const canonical = realpathSync5(current);
4048
+ if (isPathInside(cwd, canonical))
4049
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4050
+ }
4051
+ const parent = dirname8(current);
4052
+ if (parent === current)
4053
+ return;
4054
+ suffix.unshift(basename3(current));
4055
+ current = parent;
4056
+ }
4057
+ }
4058
+ function existingDirectoryInsideContext(directory, cwd) {
4059
+ if (!existsSync10(directory))
4060
+ return;
4061
+ const canonical = realpathSync5(directory);
4062
+ if (!statSync3(canonical).isDirectory())
4063
+ return;
4064
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4065
+ }
4066
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4067
+ let current = directory;
4068
+ while (isPathInside(cwd, current)) {
4069
+ const canonical = existingDirectoryInsideContext(current, cwd);
4070
+ if (canonical !== undefined)
4071
+ return canonical;
4072
+ if (current === cwd)
4073
+ return;
4074
+ current = dirname8(current);
4075
+ }
4076
+ return;
4077
+ }
3752
4078
  function formatServerLookupError(result) {
3753
4079
  if (result.status === "not_installed") {
3754
4080
  return formatNotInstalled(result);
@@ -3772,6 +4098,19 @@ function formatServerLookupError(result) {
3772
4098
  ].join(`
3773
4099
  `);
3774
4100
  }
4101
+ function formatInstallOptions(serverId, installHint) {
4102
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4103
+ if (localHint === undefined) {
4104
+ return ["To install, run:", ` ${installHint}`];
4105
+ }
4106
+ return [
4107
+ "To install in THIS repository (preferred — no global install needed):",
4108
+ ` ${localHint}`,
4109
+ "",
4110
+ "Or install it globally:",
4111
+ ` ${installHint}`
4112
+ ];
4113
+ }
3775
4114
  function formatNotInstalled(result) {
3776
4115
  const { server, installHint } = result;
3777
4116
  const extensions = server.extensions.join(", ");
@@ -3786,19 +4125,19 @@ function formatNotInstalled(result) {
3786
4125
  `Command not found: ${server.command[0]}`,
3787
4126
  ""
3788
4127
  ];
4128
+ const installOptions = formatInstallOptions(server.id, installHint);
3789
4129
  if (decision === "allowed") {
3790
4130
  return [
3791
4131
  ...header,
3792
4132
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
3793
- ` ${installHint}`
4133
+ ...installOptions.slice(1)
3794
4134
  ].join(`
3795
4135
  `);
3796
4136
  }
3797
4137
  if (!context.capabilities.installDecisionTool) {
3798
4138
  return [
3799
4139
  ...header,
3800
- "To install, run:",
3801
- ` ${installHint}`,
4140
+ ...installOptions,
3802
4141
  "",
3803
4142
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
3804
4143
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -3807,8 +4146,7 @@ function formatNotInstalled(result) {
3807
4146
  }
3808
4147
  return [
3809
4148
  ...header,
3810
- "To install, run:",
3811
- ` ${installHint}`,
4149
+ ...installOptions,
3812
4150
  "",
3813
4151
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
3814
4152
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -3819,7 +4157,7 @@ function formatNotInstalled(result) {
3819
4157
  ].join(`
3820
4158
  `);
3821
4159
  }
3822
- var READ_ONLY_RETRY_TOOLS = new Set([
4160
+ var READ_ONLY_TOOLS = new Set([
3823
4161
  "diagnostics",
3824
4162
  "definition",
3825
4163
  "references",
@@ -3828,7 +4166,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
3828
4166
  "prepareRename"
3829
4167
  ]);
3830
4168
  async function withLspClient(filePath, fn, toolName, options = {}) {
3831
- const absPath = resolvePathInsideContext(filePath);
4169
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
3832
4170
  if (isDirectoryPath(absPath)) {
3833
4171
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
3834
4172
  }
@@ -3843,9 +4181,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
3843
4181
  const acquireAndCall = async (allowRetry) => {
3844
4182
  const client = await manager.getClient(root, server, options.signal);
3845
4183
  try {
3846
- return await fn(client, root);
4184
+ return await fn(client, root, absPath);
3847
4185
  } catch (err) {
3848
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4186
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
3849
4187
  manager.invalidateClient(root, server.id, client);
3850
4188
  return acquireAndCall(false);
3851
4189
  }
@@ -3863,8 +4201,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
3863
4201
  }
3864
4202
 
3865
4203
  // ../lsp-core/src/lsp/directory-diagnostics.ts
3866
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
3867
- import { join as join5, resolve as resolve8 } from "node:path";
4204
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4205
+ import { join as join6, resolve as resolve9 } from "node:path";
3868
4206
 
3869
4207
  // ../lsp-core/src/lsp/formatters.ts
3870
4208
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -3994,7 +4332,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
3994
4332
  for (const entry of entries) {
3995
4333
  if (files.length >= maxFiles)
3996
4334
  return;
3997
- const fullPath = join5(currentDir, entry);
4335
+ const fullPath = join6(currentDir, entry);
3998
4336
  let stat;
3999
4337
  try {
4000
4338
  stat = lstatSync4(fullPath);
@@ -4019,8 +4357,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4019
4357
  if (!extension.startsWith(".")) {
4020
4358
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4021
4359
  }
4022
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4023
- if (!existsSync10(absDir)) {
4360
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4361
+ if (!existsSync11(absDir)) {
4024
4362
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4025
4363
  }
4026
4364
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -4107,7 +4445,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4107
4445
 
4108
4446
  // ../lsp-core/src/lsp/infer-extension.ts
4109
4447
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4110
- import { join as join6 } from "node:path";
4448
+ import { join as join7 } from "node:path";
4111
4449
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4112
4450
  var MAX_SCAN_ENTRIES = 500;
4113
4451
  function inferExtensionFromDirectory(directory) {
@@ -4125,7 +4463,7 @@ function inferExtensionFromDirectory(directory) {
4125
4463
  for (const entry of entries) {
4126
4464
  if (scanned >= MAX_SCAN_ENTRIES)
4127
4465
  return;
4128
- const fullPath = join6(dir, entry);
4466
+ const fullPath = join7(dir, entry);
4129
4467
  let stat;
4130
4468
  try {
4131
4469
  stat = lstatSync5(fullPath);
@@ -4300,7 +4638,7 @@ async function executeLspDiagnostics(params, signal) {
4300
4638
  const filePath = requireString(params, "filePath");
4301
4639
  const severity = severityFilter(params);
4302
4640
  try {
4303
- const absPath = resolvePathInsideContext(filePath);
4641
+ const absPath = resolveReadablePathInsideContext(filePath);
4304
4642
  if (isDirectoryPath(absPath)) {
4305
4643
  const extension = inferExtensionFromDirectory(absPath);
4306
4644
  if (!extension) {
@@ -4329,7 +4667,7 @@ async function executeLspDiagnostics(params, signal) {
4329
4667
  };
4330
4668
  return text(output2.output, details2);
4331
4669
  }
4332
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
4670
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4333
4671
  if (result.transientError) {
4334
4672
  const message = result.transientError.message;
4335
4673
  const details2 = {
@@ -4376,6 +4714,96 @@ async function executeLspDiagnostics(params, signal) {
4376
4714
  throw error;
4377
4715
  }
4378
4716
  }
4717
+ // ../lsp-core/src/lsp/format-document.ts
4718
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
4719
+ var DEFAULT_FORMATTING_OPTIONS = {
4720
+ tabSize: 4,
4721
+ insertSpaces: false,
4722
+ trimTrailingWhitespace: true,
4723
+ insertFinalNewline: true,
4724
+ trimFinalNewlines: true
4725
+ };
4726
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
4727
+ async function formatDocumentWithClient(client, filePath, options = {}) {
4728
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
4729
+ if (edits === null)
4730
+ return { status: "unavailable", reason: "capability_not_advertised" };
4731
+ if (edits.length === 0)
4732
+ return UNCHANGED;
4733
+ const before = readFileSync5(filePath, "utf-8");
4734
+ const normalized = normalizeTextEdits(before, edits, 0);
4735
+ if (normalized.text === before)
4736
+ return UNCHANGED;
4737
+ writeAtomically(filePath, normalized.text);
4738
+ await client.openFile(filePath);
4739
+ return {
4740
+ status: "formatted",
4741
+ ...lineDelta(normalized.edits)
4742
+ };
4743
+ }
4744
+ function lineDelta(edits) {
4745
+ let linesAdded = 0;
4746
+ let linesRemoved = 0;
4747
+ for (const edit of edits) {
4748
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
4749
+ linesAdded += edit.newText.split(`
4750
+ `).length;
4751
+ }
4752
+ return { linesAdded, linesRemoved };
4753
+ }
4754
+ function writeAtomically(filePath, content) {
4755
+ const tempPath = `${filePath}.omo-format.tmp`;
4756
+ writeFileSync3(tempPath, content, "utf-8");
4757
+ try {
4758
+ renameSync3(tempPath, filePath);
4759
+ } catch (error) {
4760
+ try {
4761
+ unlinkSync(tempPath);
4762
+ } catch {}
4763
+ throw error;
4764
+ }
4765
+ }
4766
+
4767
+ // ../lsp-core/src/tools/format.ts
4768
+ async function executeLspFormat(params, signal) {
4769
+ const filePath = requireString(params, "filePath");
4770
+ try {
4771
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
4772
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
4773
+ } catch (error) {
4774
+ const missingDependency = missingDependencyResult(error, {
4775
+ filePath,
4776
+ status: "unavailable",
4777
+ reason: "server_unavailable",
4778
+ linesAdded: 0,
4779
+ linesRemoved: 0
4780
+ });
4781
+ if (missingDependency)
4782
+ return missingDependency;
4783
+ throw error;
4784
+ }
4785
+ }
4786
+ function formatDetails(filePath, result) {
4787
+ if (result.status === "unavailable") {
4788
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
4789
+ }
4790
+ return {
4791
+ filePath,
4792
+ status: result.status,
4793
+ linesAdded: result.linesAdded,
4794
+ linesRemoved: result.linesRemoved
4795
+ };
4796
+ }
4797
+ function describeResult(filePath, result) {
4798
+ if (result.status === "unavailable") {
4799
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
4800
+ }
4801
+ if (result.status === "unchanged") {
4802
+ return `Already formatted: ${filePath}`;
4803
+ }
4804
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
4805
+ }
4806
+
4379
4807
  // ../lsp-core/src/tools/install-decision.ts
4380
4808
  async function executeLspInstallDecision(params) {
4381
4809
  const serverId = requireString(params, "server_id");
@@ -4404,7 +4832,7 @@ async function executeLspGotoDefinition(params, signal) {
4404
4832
  const line = requireNumber(params, "line");
4405
4833
  const character = requireNumber(params, "character");
4406
4834
  try {
4407
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
4835
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4408
4836
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4409
4837
  const details = { filePath, line, character, locations };
4410
4838
  if (locations.length === 0)
@@ -4429,7 +4857,7 @@ async function executeLspFindReferences(params, signal) {
4429
4857
  const character = requireNumber(params, "character");
4430
4858
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4431
4859
  try {
4432
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4860
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4433
4861
  const references = Array.isArray(result) ? result : [];
4434
4862
  const total = references.length;
4435
4863
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4471,7 +4899,7 @@ async function executeLspPrepareRename(params, signal) {
4471
4899
  const line = requireNumber(params, "line");
4472
4900
  const character = requireNumber(params, "character");
4473
4901
  try {
4474
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
4902
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4475
4903
  const details = { filePath, line, character, result };
4476
4904
  return text(formatPrepareRenameResult(result), details);
4477
4905
  } catch (error) {
@@ -4492,7 +4920,7 @@ async function executeLspRename(params, signal) {
4492
4920
  const character = requireNumber(params, "character");
4493
4921
  const newName = requireString(params, "newName");
4494
4922
  try {
4495
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
4923
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4496
4924
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4497
4925
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4498
4926
  } catch (error) {
@@ -4572,7 +5000,7 @@ async function executeLspSymbols(params, signal) {
4572
5000
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4573
5001
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
4574
5002
  }
4575
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5003
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4576
5004
  return formatSymbolsResult(filePath, scope, symbols, limit);
4577
5005
  } catch (error) {
4578
5006
  const query = optionalString(params, "query");
@@ -4708,6 +5136,16 @@ var LSP_MCP_TOOLS = [
4708
5136
  }, ["filePath", "line", "character", "newName"]),
4709
5137
  execute: executeLspRename
4710
5138
  },
5139
+ {
5140
+ name: "format",
5141
+ aliases: ["lsp_format"],
5142
+ title: "LSP Format",
5143
+ description: "Format a source file with its language server and write the returned edits to disk.",
5144
+ inputSchema: objectSchema({
5145
+ filePath: { type: "string", description: "Source file path to format." }
5146
+ }, ["filePath"]),
5147
+ execute: executeLspFormat
5148
+ },
4711
5149
  {
4712
5150
  name: "install_decision",
4713
5151
  aliases: ["lsp_install_decision"],
@@ -4741,16 +5179,17 @@ function coerceToolArguments(value) {
4741
5179
  return isRecord7(value) ? value : {};
4742
5180
  }
4743
5181
  export {
4744
- isRecord7 as isRecord,
4745
- executeLspTool,
4746
- executeLspSymbols,
4747
- executeLspStatus,
4748
- executeLspRename,
4749
- executeLspPrepareRename,
4750
- executeLspInstallDecision,
4751
- executeLspGotoDefinition,
4752
- executeLspFindReferences,
4753
- executeLspDiagnostics,
5182
+ LSP_MCP_TOOLS,
4754
5183
  coerceToolArguments,
4755
- LSP_MCP_TOOLS
5184
+ executeLspDiagnostics,
5185
+ executeLspFindReferences,
5186
+ executeLspFormat,
5187
+ executeLspGotoDefinition,
5188
+ executeLspInstallDecision,
5189
+ executeLspPrepareRename,
5190
+ executeLspRename,
5191
+ executeLspStatus,
5192
+ executeLspSymbols,
5193
+ executeLspTool,
5194
+ isRecord7 as isRecord
4756
5195
  };