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

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 (583) 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 +22572 -20322
  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 +22190 -19917
  38. package/dist/config/schema/commands.d.ts +1 -1
  39. package/dist/config/schema/hooks.d.ts +1 -1
  40. package/dist/config/schema/oh-my-opencode-config.d.ts +4 -1
  41. package/dist/config/schema/ulw-execute.d.ts +5 -0
  42. package/dist/config/validate.d.ts +2 -0
  43. package/dist/create-hooks.d.ts +3 -1
  44. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  45. package/dist/features/btw-side/context-injector.d.ts +15 -0
  46. package/dist/features/btw-side/index.d.ts +8 -0
  47. package/dist/features/btw-side/metadata.d.ts +15 -0
  48. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  49. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  50. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  51. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  52. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  53. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  54. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  55. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  56. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  57. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  58. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  59. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  60. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  61. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  62. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  63. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  64. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  65. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  66. package/dist/features/builtin-commands/types.d.ts +1 -1
  67. package/dist/features/opengateway-provider/index.d.ts +13 -0
  68. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
  69. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  70. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  71. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  72. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  73. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  74. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  75. package/dist/hooks/atlas/types.d.ts +1 -0
  76. package/dist/hooks/index.d.ts +1 -1
  77. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  78. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  79. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  80. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  81. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  82. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  83. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  84. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  85. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  86. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  87. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  88. package/dist/index.js +12573 -6957
  89. package/dist/oh-my-opencode.schema.json +15 -2
  90. package/dist/plugin/chat-message/types.d.ts +3 -3
  91. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  92. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  93. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  94. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  95. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  96. package/dist/plugin/messages-transform.d.ts +1 -0
  97. package/dist/shared/index.d.ts +2 -0
  98. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  99. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  100. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  101. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  102. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  103. package/dist/shared/shell-env.d.ts +1 -1
  104. package/dist/skills/ast-grep/AGENTS.md +51 -0
  105. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  106. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  107. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  108. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  109. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  110. package/dist/skills/data-scientist/SKILL.md +99 -239
  111. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  112. package/dist/skills/data-scientist/references/placement.md +74 -0
  113. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  114. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  115. package/dist/skills/data-scientist/references/visualization.md +64 -0
  116. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  117. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  118. package/dist/skills/debugging/SKILL.md +2 -0
  119. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  120. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  121. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  122. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  123. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  124. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  125. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  126. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  127. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  128. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  129. package/dist/skills/debugging/references/tools/dap.md +103 -0
  130. package/dist/skills/debugging/references/tools/frida.md +193 -0
  131. package/dist/skills/frontend/SKILL.md +11 -7
  132. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  133. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  134. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  135. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  136. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  137. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  138. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  139. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  140. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  141. package/dist/skills/review-work/SKILL.md +3 -3
  142. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  143. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  144. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  145. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  146. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  147. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  148. package/dist/skills/ulw-plan/SKILL.md +6 -6
  149. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  150. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  151. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  152. package/dist/skills/ulw-research/SKILL.md +4 -2
  153. package/dist/skills/visual-qa/AGENTS.md +58 -0
  154. package/dist/skills/visual-qa/SKILL.md +3 -2
  155. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  156. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  157. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  158. package/dist/tools/delegate-task/types.d.ts +3 -0
  159. package/dist/tui.d.ts +12 -0
  160. package/dist/tui.js +11480 -11512
  161. package/package.json +42 -36
  162. package/packages/git-bash-mcp/dist/cli.js +5 -1
  163. package/packages/git-bash-mcp/package.json +1 -1
  164. package/packages/lsp-core/src/index.ts +1 -0
  165. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  166. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  167. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  168. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +66 -13
  169. package/packages/lsp-core/src/lsp/client-wrapper.ts +95 -23
  170. package/packages/lsp-core/src/lsp/client.ts +26 -0
  171. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  172. package/packages/lsp-core/src/lsp/constants.ts +1 -0
  173. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  174. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  175. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  176. package/packages/lsp-core/src/lsp/manager.ts +34 -1
  177. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  178. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  179. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  180. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  181. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  182. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  183. package/packages/lsp-core/src/lsp/transport.ts +9 -0
  184. package/packages/lsp-core/src/lsp/types.ts +8 -0
  185. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  186. package/packages/lsp-core/src/lsp/workspace-markers.ts +1 -0
  187. package/packages/lsp-core/src/request-context.test.ts +29 -0
  188. package/packages/lsp-core/src/request-context.ts +1 -1
  189. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  190. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  191. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  192. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  193. package/packages/lsp-core/src/tools/format.ts +56 -0
  194. package/packages/lsp-core/src/tools/index.ts +1 -0
  195. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  196. package/packages/lsp-core/src/tools/rename.ts +4 -2
  197. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  198. package/packages/lsp-core/src/tools/types.ts +10 -0
  199. package/packages/lsp-daemon/dist/cli.js +645 -296
  200. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  201. package/packages/lsp-daemon/dist/client.js +605 -253
  202. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  203. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  204. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  205. package/packages/lsp-daemon/dist/index.js +609 -262
  206. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  207. package/packages/lsp-daemon/package.json +1 -1
  208. package/packages/lsp-tools-mcp/dist/cli.js +564 -217
  209. package/packages/lsp-tools-mcp/dist/lsp/manager.js +115 -92
  210. package/packages/lsp-tools-mcp/dist/mcp.js +566 -219
  211. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  212. package/packages/lsp-tools-mcp/dist/tools.js +571 -227
  213. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  214. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  215. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  216. package/packages/omo-codex/plugin/README.md +1 -1
  217. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
  218. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  219. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  220. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  221. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +293 -116
  222. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +245 -84
  223. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  224. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  225. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  226. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  227. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  228. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  229. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  230. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  231. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  232. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  233. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  234. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  235. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  236. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  237. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  238. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  239. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  240. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  241. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  242. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  243. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  244. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  245. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  246. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  247. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  248. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +596 -267
  249. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  250. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  251. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  252. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  253. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  254. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  255. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  256. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  257. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  258. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  259. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  260. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  261. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  262. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  263. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  264. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  265. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  266. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  267. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  268. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  269. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  270. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  271. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  272. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  273. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  274. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  275. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  276. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  277. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  278. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  279. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  280. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  281. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  282. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  283. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  284. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  285. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  286. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  287. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  288. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  289. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  290. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  291. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  292. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  293. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  294. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  295. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  296. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  297. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  298. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  299. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  300. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  301. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  302. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  303. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  304. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  305. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  306. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  307. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  308. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  309. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  310. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  311. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  312. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  313. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  314. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  315. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  316. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  317. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  318. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  319. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  320. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  321. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  322. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  323. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  324. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  325. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  326. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  327. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  328. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  329. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  330. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  331. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +16 -0
  332. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  333. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  334. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  335. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
  336. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  337. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +11 -1
  338. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +24 -14
  339. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  340. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  341. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  342. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  343. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  344. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  345. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  346. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  347. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
  348. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
  349. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  350. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  351. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  352. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  353. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  354. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  355. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  356. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  357. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  358. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  359. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  360. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  361. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  362. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  363. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  364. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  365. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  366. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  367. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  368. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  369. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  370. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  371. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  372. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  373. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  374. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  375. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  376. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  377. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  378. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  379. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  380. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  381. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  382. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  383. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  384. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  385. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  386. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  387. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  388. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  389. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  390. package/packages/omo-codex/plugin/package-lock.json +681 -395
  391. package/packages/omo-codex/plugin/package.json +2 -2
  392. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  393. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  394. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  395. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  396. package/packages/omo-codex/plugin/shared/package.json +3 -4
  397. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  398. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  399. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  400. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  401. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  402. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  403. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  404. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  405. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  406. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  407. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  408. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  409. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  410. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  411. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  412. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  413. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  414. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  415. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  416. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  417. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  418. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  419. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  420. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  421. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  422. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  423. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  424. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  425. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  426. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  427. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  428. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  429. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  430. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  431. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  432. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  433. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  434. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  435. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  436. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  437. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  438. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  439. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  440. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  441. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  442. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  443. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  444. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  445. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  446. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  447. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  448. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  449. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  450. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  451. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  452. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  453. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  454. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  455. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  456. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  457. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  458. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  459. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  460. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
  461. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  462. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  463. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  464. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  465. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  466. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  467. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  468. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  469. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  470. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  471. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  472. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  473. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  474. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  475. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  476. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  477. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  478. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  479. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  480. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
  481. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  482. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  483. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  484. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  485. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  486. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  487. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  488. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  489. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  490. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  491. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  492. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  493. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  494. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  495. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  496. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  497. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  498. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  499. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  500. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  501. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  502. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  503. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  504. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  505. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  506. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  507. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  508. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  509. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  510. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  511. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  512. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  513. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  514. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  515. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  516. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  517. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  518. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  519. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  520. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  521. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  522. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  523. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  524. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  525. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  526. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  527. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  528. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  529. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  530. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  531. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  532. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  533. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  534. package/script/qa/xterm-live-terminal.mjs +18 -2
  535. package/dist/config/schema/start-work.d.ts +0 -5
  536. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  537. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  538. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  539. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  540. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  541. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  542. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  543. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  544. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  545. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  546. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  547. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  548. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  549. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  550. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  551. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  552. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  553. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  554. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  555. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  556. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  557. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  558. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  559. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  560. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  561. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  562. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  563. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  564. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  565. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  566. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  567. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  568. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  569. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  570. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  571. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  572. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  573. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  574. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  575. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  576. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  577. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  578. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  579. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  580. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  581. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  582. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  583. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -25,28 +25,22 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
25
25
  var REQUEST_TIMEOUT_MS = 15000;
26
26
  var INIT_TIMEOUT_MS = 60000;
27
27
  var IDLE_TIMEOUT_MS = 5 * 60000;
28
+ var MAX_RESIDENT_CLIENTS = 6;
28
29
  var REAPER_INTERVAL_MS = 60000;
29
30
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
30
31
  var STOP_SIGKILL_GRACE_MS = 1000;
31
32
 
32
33
  // ../lsp-core/src/lsp/errors.ts
33
34
  class LspConnectionClosedError extends Error {
34
- serverId;
35
- root;
36
- name = "LspConnectionClosedError";
37
35
  constructor(serverId, root, message) {
38
36
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
39
37
  this.serverId = serverId;
40
38
  this.root = root;
39
+ this.name = "LspConnectionClosedError";
41
40
  }
42
41
  }
43
42
 
44
43
  class LspProcessExitedError extends Error {
45
- serverId;
46
- root;
47
- exitCode;
48
- stderrTail;
49
- name = "LspProcessExitedError";
50
44
  constructor(serverId, root, exitCode, stderrTail) {
51
45
  const stderrSuffix = stderrTail ? `
52
46
  stderr tail: ${stderrTail}` : "";
@@ -55,46 +49,49 @@ stderr tail: ${stderrTail}` : "";
55
49
  this.root = root;
56
50
  this.exitCode = exitCode;
57
51
  this.stderrTail = stderrTail;
52
+ this.name = "LspProcessExitedError";
58
53
  }
59
54
  }
60
55
 
61
56
  class LspRequestTimeoutError extends Error {
62
- method;
63
- stderrTail;
64
- name = "LspRequestTimeoutError";
65
57
  constructor(method, stderrTail) {
66
58
  const stderrSuffix = stderrTail ? `
67
59
  recent stderr: ${stderrTail}` : "";
68
60
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
69
61
  this.method = method;
70
62
  this.stderrTail = stderrTail;
63
+ this.name = "LspRequestTimeoutError";
71
64
  }
72
65
  }
73
66
 
74
67
  class LspInvalidPathError extends Error {
75
- name = "LspInvalidPathError";
68
+ constructor() {
69
+ super(...arguments);
70
+ this.name = "LspInvalidPathError";
71
+ }
76
72
  }
77
73
 
78
74
  class LspServerLookupError extends Error {
79
- lookup;
80
- name = "LspServerLookupError";
81
75
  constructor(message, lookup) {
82
76
  super(message);
83
77
  this.lookup = lookup;
78
+ this.name = "LspServerLookupError";
84
79
  }
85
80
  }
86
81
 
87
82
  class LspServerInitializingError extends Error {
88
- originalError;
89
- name = "LspServerInitializingError";
90
83
  constructor(originalError) {
91
84
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
92
85
  this.originalError = originalError;
86
+ this.name = "LspServerInitializingError";
93
87
  }
94
88
  }
95
89
 
96
90
  class LspProcessSpawnError extends Error {
97
- name = "LspProcessSpawnError";
91
+ constructor() {
92
+ super(...arguments);
93
+ this.name = "LspProcessSpawnError";
94
+ }
98
95
  }
99
96
  function isLspDeadConnectionError(err) {
100
97
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -110,20 +107,31 @@ var METHOD_NOT_FOUND = -32601;
110
107
  var INTERNAL_ERROR = -32603;
111
108
 
112
109
  class JsonRpcConnection {
113
- reader;
114
- writer;
115
- pendingRequests = new Map;
116
- notificationHandlers = new Map;
117
- requestHandlers = new Map;
118
- closeHandlers = [];
119
- errorHandlers = [];
120
- inputBuffer = Buffer.alloc(0);
121
- nextRequestId = 1;
122
- listening = false;
123
- disposed = false;
124
110
  constructor(reader, writer) {
125
111
  this.reader = reader;
126
112
  this.writer = writer;
113
+ this.pendingRequests = new Map;
114
+ this.notificationHandlers = new Map;
115
+ this.requestHandlers = new Map;
116
+ this.closeHandlers = [];
117
+ this.errorHandlers = [];
118
+ this.inputBuffer = Buffer.alloc(0);
119
+ this.nextRequestId = 1;
120
+ this.listening = false;
121
+ this.disposed = false;
122
+ this.handleData = (chunk) => {
123
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
124
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
125
+ this.drainInputBuffer();
126
+ };
127
+ this.handleClose = () => {
128
+ for (const handler of this.closeHandlers) {
129
+ handler();
130
+ }
131
+ };
132
+ this.handleStreamError = (error) => {
133
+ this.emitError(error);
134
+ };
127
135
  }
128
136
  listen() {
129
137
  if (this.listening)
@@ -244,19 +252,6 @@ class JsonRpcConnection {
244
252
  this.notificationHandlers.clear();
245
253
  this.requestHandlers.clear();
246
254
  }
247
- handleData = (chunk) => {
248
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
249
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
250
- this.drainInputBuffer();
251
- };
252
- handleClose = () => {
253
- for (const handler of this.closeHandlers) {
254
- handler();
255
- }
256
- };
257
- handleStreamError = (error) => {
258
- this.emitError(error);
259
- };
260
255
  drainInputBuffer() {
261
256
  while (true) {
262
257
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -604,31 +599,26 @@ function isPosition(value) {
604
599
 
605
600
  // ../lsp-core/src/lsp/transport.ts
606
601
  class LspClientNotStartedError extends Error {
607
- serverId;
608
- root;
609
- name = "LspClientNotStartedError";
610
602
  constructor(serverId, root) {
611
603
  super("LSP client not started");
612
604
  this.serverId = serverId;
613
605
  this.root = root;
606
+ this.name = "LspClientNotStartedError";
614
607
  }
615
608
  }
616
609
 
617
610
  class LspClientTransport {
618
- root;
619
- server;
620
- proc = null;
621
- connection = null;
622
- stderrBuffer = [];
623
- processExited = false;
624
- diagnosticsStore = new Map;
625
- requestTimeoutMs;
626
- initializeTimeoutMs;
627
- workspaceApplyEditHandler = null;
628
- diagnosticPullSupported = false;
629
611
  constructor(root, server, timeouts = {}) {
630
612
  this.root = root;
631
613
  this.server = server;
614
+ this.proc = null;
615
+ this.connection = null;
616
+ this.stderrBuffer = [];
617
+ this.processExited = false;
618
+ this.diagnosticsStore = new Map;
619
+ this.workspaceApplyEditHandler = null;
620
+ this.diagnosticPullSupported = false;
621
+ this.documentFormattingSupported = false;
632
622
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
633
623
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
634
624
  }
@@ -650,6 +640,12 @@ class LspClientTransport {
650
640
  isDiagnosticPullSupported() {
651
641
  return this.diagnosticPullSupported;
652
642
  }
643
+ setDocumentFormattingSupported(supported) {
644
+ this.documentFormattingSupported = supported;
645
+ }
646
+ isDocumentFormattingSupported() {
647
+ return this.documentFormattingSupported;
648
+ }
653
649
  handlePublishDiagnostics(params) {
654
650
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
655
651
  }
@@ -863,6 +859,14 @@ function supportsDiagnosticPull(capabilities) {
863
859
  return false;
864
860
  return Object.hasOwn(capabilities, "diagnosticProvider");
865
861
  }
862
+ function supportsDocumentFormatting(capabilities) {
863
+ if (capabilities === undefined)
864
+ return false;
865
+ const provider = capabilities.documentFormattingProvider;
866
+ if (provider === undefined || provider === null || provider === false)
867
+ return false;
868
+ return provider === true || typeof provider === "object";
869
+ }
866
870
 
867
871
  class LspClientConnection extends LspClientTransport {
868
872
  async initialize() {
@@ -879,6 +883,7 @@ class LspClientConnection extends LspClientTransport {
879
883
  references: {},
880
884
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
881
885
  publishDiagnostics: {},
886
+ formatting: { dynamicRegistration: false },
882
887
  rename: {
883
888
  prepareSupport: true,
884
889
  prepareSupportDefaultBehavior: 1
@@ -920,6 +925,7 @@ class LspClientConnection extends LspClientTransport {
920
925
  initializationOptions: this.server.initialization
921
926
  }, { timeoutMs: this.initializeTimeoutMs });
922
927
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
928
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
923
929
  await this.sendNotification("initialized", {});
924
930
  await this.sendNotification("workspace/didChangeConfiguration", {
925
931
  settings: { json: { validate: { enable: true } } }
@@ -1135,16 +1141,12 @@ function movedPath(candidate, oldPath, newPath) {
1135
1141
  }
1136
1142
 
1137
1143
  class WorkspaceDocumentState {
1138
- sendNotification;
1139
- clearDiagnostics;
1140
- openDocuments = new Map;
1141
- openByUri = new Map;
1142
- openPromises = new Map;
1143
- now;
1144
- versionlessPublishQuiescenceMs;
1145
1144
  constructor(sendNotification, clearDiagnostics, options = {}) {
1146
1145
  this.sendNotification = sendNotification;
1147
1146
  this.clearDiagnostics = clearDiagnostics;
1147
+ this.openDocuments = new Map;
1148
+ this.openByUri = new Map;
1149
+ this.openPromises = new Map;
1148
1150
  this.now = options.now ?? (() => Date.now());
1149
1151
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1150
1152
  }
@@ -1408,13 +1410,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
1408
1410
  import { fileURLToPath } from "node:url";
1409
1411
 
1410
1412
  class WorkspaceEditPathError extends Error {
1411
- path;
1412
- detail;
1413
- name = "WorkspaceEditPathError";
1414
1413
  constructor(path, detail) {
1415
1414
  super(`${detail}: ${path}`);
1416
1415
  this.path = path;
1417
1416
  this.detail = detail;
1417
+ this.name = "WorkspaceEditPathError";
1418
1418
  }
1419
1419
  }
1420
1420
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1706,13 +1706,11 @@ function canonicalFingerprint(operations) {
1706
1706
 
1707
1707
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1708
1708
  class WorkspaceEditValidationError extends Error {
1709
- changeIndex;
1710
- detail;
1711
- name = "WorkspaceEditValidationError";
1712
1709
  constructor(changeIndex, detail) {
1713
1710
  super(`change ${changeIndex}: ${detail}`);
1714
1711
  this.changeIndex = changeIndex;
1715
1712
  this.detail = detail;
1713
+ this.name = "WorkspaceEditValidationError";
1716
1714
  }
1717
1715
  }
1718
1716
 
@@ -2210,10 +2208,9 @@ function simulateDelete(operation, virtual) {
2210
2208
  import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2211
2209
  import { dirname as dirname3, resolve as resolve4 } from "node:path";
2212
2210
  class WorkspaceSnapshotBuilder {
2213
- workspaceRoot;
2214
- snapshots = new Map;
2215
2211
  constructor(workspaceRoot) {
2216
2212
  this.workspaceRoot = workspaceRoot;
2213
+ this.snapshots = new Map;
2217
2214
  }
2218
2215
  build(operations) {
2219
2216
  this.add(this.workspaceRoot, false);
@@ -2257,8 +2254,10 @@ function snapshotOperations(operations, workspaceRoot) {
2257
2254
 
2258
2255
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2259
2256
  class PlanPathIndex {
2260
- firstChangeByPath = new Map;
2261
- reportedPathByCanonical = new Map;
2257
+ constructor() {
2258
+ this.firstChangeByPath = new Map;
2259
+ this.reportedPathByCanonical = new Map;
2260
+ }
2262
2261
  build(operations) {
2263
2262
  for (const operation of operations) {
2264
2263
  switch (operation.kind) {
@@ -2347,14 +2346,11 @@ function isRecord3(value) {
2347
2346
  }
2348
2347
 
2349
2348
  class WorkspaceMutationController {
2350
- workspaceRoot;
2351
- documents;
2352
- activeLease = null;
2353
- nextLeaseId = 1;
2354
- io;
2355
2349
  constructor(workspaceRoot, documents) {
2356
2350
  this.workspaceRoot = workspaceRoot;
2357
2351
  this.documents = documents;
2352
+ this.activeLease = null;
2353
+ this.nextLeaseId = 1;
2358
2354
  }
2359
2355
  setIo(io) {
2360
2356
  this.io = io;
@@ -2467,12 +2463,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2467
2463
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2468
2464
 
2469
2465
  class LspClient extends LspClientConnection {
2470
- diagnosticPullErrors = [];
2471
- documents;
2472
- workspaceMutations;
2473
- diagnosticsFreshnessTimeoutMs;
2474
2466
  constructor(root, server, options = {}) {
2475
2467
  super(root, server, options);
2468
+ this.diagnosticPullErrors = [];
2476
2469
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2477
2470
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2478
2471
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
@@ -2527,6 +2520,18 @@ class LspClient extends LspClientConnection {
2527
2520
  textDocument: { uri: pathToFileURL3(absPath).href }
2528
2521
  }, options);
2529
2522
  }
2523
+ async formatDocument(filePath, options, signal) {
2524
+ if (!this.isDocumentFormattingSupported())
2525
+ return null;
2526
+ const absPath = this.resolveWorkspacePath(filePath);
2527
+ await this.openFile(absPath);
2528
+ const requestOptions = signal === undefined ? {} : { signal };
2529
+ const edits = await this.sendRequest("textDocument/formatting", {
2530
+ textDocument: { uri: pathToFileURL3(absPath).href },
2531
+ options
2532
+ }, requestOptions);
2533
+ return edits ?? [];
2534
+ }
2530
2535
  async workspaceSymbols(query, signal) {
2531
2536
  const options = signal === undefined ? {} : { signal };
2532
2537
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2772,18 +2777,14 @@ function awaitWithSignal(promise, signal) {
2772
2777
  }
2773
2778
 
2774
2779
  class LspManager {
2775
- clients = new Map;
2776
- reaperHandle = null;
2777
- signalDisposer = null;
2778
- disposed = false;
2779
- idleTimeoutMs;
2780
- initTimeoutMs;
2781
- reaperIntervalMs;
2782
- clientFactory;
2783
- now;
2784
2780
  constructor(options = {}) {
2781
+ this.clients = new Map;
2782
+ this.reaperHandle = null;
2783
+ this.signalDisposer = null;
2784
+ this.disposed = false;
2785
2785
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2786
2786
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2787
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2787
2788
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2788
2789
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2789
2790
  this.now = options.now ?? (() => Date.now());
@@ -2817,6 +2818,26 @@ class LspManager {
2817
2818
  }
2818
2819
  }
2819
2820
  }
2821
+ evictForAdmission() {
2822
+ while (this.clients.size >= this.maxResidentClients) {
2823
+ const victim = this.leastRecentlyUsedIdleClient();
2824
+ if (!victim)
2825
+ return;
2826
+ this.clients.delete(victim.key);
2827
+ stopClientBestEffort(victim.managed.client);
2828
+ }
2829
+ }
2830
+ leastRecentlyUsedIdleClient() {
2831
+ let candidate = null;
2832
+ for (const [key, managed] of this.clients) {
2833
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
2834
+ continue;
2835
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
2836
+ candidate = { key, managed };
2837
+ }
2838
+ }
2839
+ return candidate;
2840
+ }
2820
2841
  async tryDeleteIfOrphaned(key, managed) {
2821
2842
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
2822
2843
  this.clients.delete(key);
@@ -2863,6 +2884,7 @@ class LspManager {
2863
2884
  managed.lastUsedAt = this.now();
2864
2885
  return managed.client;
2865
2886
  }
2887
+ this.evictForAdmission();
2866
2888
  const client = this.clientFactory(root, server);
2867
2889
  const initStartedAt = this.now();
2868
2890
  const initPromise = (async () => {
@@ -2925,6 +2947,7 @@ class LspManager {
2925
2947
  const key = this.getKey(root, server.id);
2926
2948
  if (this.clients.has(key))
2927
2949
  return;
2950
+ this.evictForAdmission();
2928
2951
  const client = this.clientFactory(root, server);
2929
2952
  const initStartedAt = this.now();
2930
2953
  const initPromise = (async () => {
@@ -3285,7 +3308,11 @@ function createParentWatchdog(config, onDeadParent) {
3285
3308
  const probeAlive = config.probeAlive ?? isProcessAlive;
3286
3309
  let fired = false;
3287
3310
  const timer = setInterval(() => {
3288
- if (fired || probeAlive(parentPid))
3311
+ if (fired)
3312
+ return;
3313
+ const alive = probeAlive(parentPid);
3314
+ config.onPoll?.(alive);
3315
+ if (alive)
3289
3316
  return;
3290
3317
  fired = true;
3291
3318
  onDeadParent(parentPid, pollIntervalMs);
@@ -3320,8 +3347,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
3320
3347
  };
3321
3348
  }
3322
3349
  // ../lsp-core/src/lsp/client-wrapper.ts
3323
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
3324
- import { dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
3350
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
3351
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
3325
3352
 
3326
3353
  // ../lsp-core/src/request-context.ts
3327
3354
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3330,18 +3357,17 @@ import { homedir } from "node:os";
3330
3357
  import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
3331
3358
 
3332
3359
  class LspRequestContextParseError extends Error {
3333
- code;
3334
- name = "LspRequestContextParseError";
3335
3360
  constructor(code, message) {
3336
3361
  super(message);
3337
3362
  this.code = code;
3363
+ this.name = "LspRequestContextParseError";
3338
3364
  }
3339
3365
  }
3340
3366
 
3341
3367
  class LspRequestContextUnavailableError extends Error {
3342
- name = "LspRequestContextUnavailableError";
3343
3368
  constructor() {
3344
3369
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
3370
+ this.name = "LspRequestContextUnavailableError";
3345
3371
  }
3346
3372
  }
3347
3373
  var storage = new AsyncLocalStorage;
@@ -3371,7 +3397,7 @@ function contextEnv(key) {
3371
3397
  }
3372
3398
  function createStandaloneMcpRequestContext(input = {}) {
3373
3399
  const env = input.env ?? process.env;
3374
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
3400
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
3375
3401
  const home = input.homeDir ?? homedir();
3376
3402
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
3377
3403
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -3502,57 +3528,43 @@ function errorCode(error) {
3502
3528
  return typeof code === "string" ? code : undefined;
3503
3529
  }
3504
3530
 
3505
- // ../lsp-core/src/lsp/server-install-state.ts
3506
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3507
- import { dirname as dirname5 } from "node:path";
3508
- function getInstallDecisionsPath() {
3509
- return lspRequestContext().installDecisionsPath;
3510
- }
3511
- function loadInstallDecisions() {
3512
- const path = getInstallDecisionsPath();
3513
- if (!existsSync6(path))
3514
- return {};
3515
- try {
3516
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3517
- return isInstallDecisions(parsed) ? parsed : {};
3518
- } catch {
3519
- return {};
3531
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3532
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3533
+ import { dirname as dirname5, join as join3 } from "node:path";
3534
+
3535
+ // ../lsp-core/src/lsp/workspace-markers.ts
3536
+ var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
3537
+
3538
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3539
+ function findWorkspaceRootOutsideContext(directory) {
3540
+ const marked = nearestMarkedAncestor(directory);
3541
+ if (marked !== undefined)
3542
+ return marked;
3543
+ return realpathSync4(nearestExistingAncestor(directory));
3544
+ }
3545
+ function nearestMarkedAncestor(directory) {
3546
+ let current = directory;
3547
+ for (;; ) {
3548
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3549
+ return realpathSync4(current);
3550
+ }
3551
+ const parent = dirname5(current);
3552
+ if (parent === current)
3553
+ return;
3554
+ current = parent;
3520
3555
  }
3521
3556
  }
3522
- function loadInstallDecision(serverId) {
3523
- return loadInstallDecisions()[serverId];
3524
- }
3525
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3526
- const decisions = loadInstallDecisions();
3527
- decisions[serverId] = { decision, decidedAt };
3528
- writeInstallDecisions(decisions);
3529
- }
3530
- function isInstallDecision(value) {
3531
- return value === "declined" || value === "allowed";
3532
- }
3533
- function writeInstallDecisions(decisions) {
3534
- const path = getInstallDecisionsPath();
3535
- mkdirSync(dirname5(path), { recursive: true });
3536
- const tmpPath = `${path}.tmp`;
3537
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3538
- `, "utf8");
3539
- renameSync2(tmpPath, path);
3540
- }
3541
- function isInstallDecisions(value) {
3542
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3543
- }
3544
- function isInstallDecisionRecord(value) {
3545
- if (!isRecord5(value))
3546
- return false;
3547
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3548
- }
3549
- function isRecord5(value) {
3550
- return typeof value === "object" && value !== null && !Array.isArray(value);
3557
+ function nearestExistingAncestor(directory) {
3558
+ let current = directory;
3559
+ while (!existsSync6(current)) {
3560
+ const parent = dirname5(current);
3561
+ if (parent === current)
3562
+ return current;
3563
+ current = parent;
3564
+ }
3565
+ return current;
3551
3566
  }
3552
3567
 
3553
- // ../lsp-core/src/lsp/config-loader.ts
3554
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3555
-
3556
3568
  // ../lsp-core/src/lsp/server-definitions.ts
3557
3569
  var LSP_INSTALL_HINTS = {
3558
3570
  typescript: "npm install -g typescript-language-server typescript",
@@ -3598,6 +3610,26 @@ var LSP_INSTALL_HINTS = {
3598
3610
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3599
3611
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3600
3612
  };
3613
+ var LSP_LOCAL_INSTALL_HINTS = {
3614
+ typescript: "bun add -d typescript-language-server typescript",
3615
+ vue: "bun add -d @vue/language-server",
3616
+ eslint: "bun add -d vscode-langservers-extracted",
3617
+ oxlint: "bun add -d oxlint",
3618
+ biome: "bun add -d @biomejs/biome",
3619
+ svelte: "bun add -d svelte-language-server",
3620
+ astro: "bun add -d @astrojs/language-server",
3621
+ bash: "bun add -d bash-language-server",
3622
+ "bash-ls": "bun add -d bash-language-server",
3623
+ "yaml-ls": "bun add -d yaml-language-server",
3624
+ php: "bun add -d intelephense",
3625
+ prisma: "bun add -d prisma",
3626
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3627
+ pyright: "uv add --dev pyright",
3628
+ basedpyright: "uv add --dev basedpyright",
3629
+ ruff: "uv add --dev ruff",
3630
+ ty: "uv add --dev ty",
3631
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3632
+ };
3601
3633
  var BUILTIN_SERVERS = {
3602
3634
  typescript: {
3603
3635
  command: ["typescript-language-server", "--stdio"],
@@ -3700,7 +3732,56 @@ var BUILTIN_SERVERS = {
3700
3732
  }
3701
3733
  };
3702
3734
 
3735
+ // ../lsp-core/src/lsp/server-install-state.ts
3736
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3737
+ import { dirname as dirname6 } from "node:path";
3738
+ function getInstallDecisionsPath() {
3739
+ return lspRequestContext().installDecisionsPath;
3740
+ }
3741
+ function loadInstallDecisions() {
3742
+ const path = getInstallDecisionsPath();
3743
+ if (!existsSync7(path))
3744
+ return {};
3745
+ try {
3746
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3747
+ return isInstallDecisions(parsed) ? parsed : {};
3748
+ } catch {
3749
+ return {};
3750
+ }
3751
+ }
3752
+ function loadInstallDecision(serverId) {
3753
+ return loadInstallDecisions()[serverId];
3754
+ }
3755
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3756
+ const decisions = loadInstallDecisions();
3757
+ decisions[serverId] = { decision, decidedAt };
3758
+ writeInstallDecisions(decisions);
3759
+ }
3760
+ function isInstallDecision(value) {
3761
+ return value === "declined" || value === "allowed";
3762
+ }
3763
+ function writeInstallDecisions(decisions) {
3764
+ const path = getInstallDecisionsPath();
3765
+ mkdirSync(dirname6(path), { recursive: true });
3766
+ const tmpPath = `${path}.tmp`;
3767
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3768
+ `, "utf8");
3769
+ renameSync2(tmpPath, path);
3770
+ }
3771
+ function isInstallDecisions(value) {
3772
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3773
+ }
3774
+ function isInstallDecisionRecord(value) {
3775
+ if (!isRecord5(value))
3776
+ return false;
3777
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3778
+ }
3779
+ function isRecord5(value) {
3780
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3781
+ }
3782
+
3703
3783
  // ../lsp-core/src/lsp/config-loader.ts
3784
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3704
3785
  function getProjectConfigPaths() {
3705
3786
  return lspRequestContext().projectConfigPaths;
3706
3787
  }
@@ -3708,7 +3789,7 @@ function getUserConfigPath() {
3708
3789
  return lspRequestContext().userConfigPath;
3709
3790
  }
3710
3791
  function loadJsonFile(path) {
3711
- if (!existsSync7(path))
3792
+ if (!existsSync8(path))
3712
3793
  return null;
3713
3794
  try {
3714
3795
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3896,54 +3977,155 @@ function getDisabledServerIds() {
3896
3977
  }
3897
3978
 
3898
3979
  // ../lsp-core/src/lsp/server-installation.ts
3899
- import { existsSync as existsSync8 } from "node:fs";
3900
- import { delimiter as delimiter3, join as join3 } from "node:path";
3901
- function isServerInstalled(command, _workingDirectory) {
3902
- if (command.length === 0)
3903
- return false;
3904
- const [cmd] = command;
3905
- if (!cmd)
3906
- return false;
3907
- if (cmd.includes("/") || cmd.includes("\\")) {
3908
- if (existsSync8(cmd))
3909
- return true;
3980
+ import { existsSync as existsSync9 } from "node:fs";
3981
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
3982
+ var LOCAL_BIN_RULES = [
3983
+ {
3984
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
3985
+ binDirs: [join4("node_modules", ".bin")]
3986
+ },
3987
+ {
3988
+ markers: [
3989
+ "pyproject.toml",
3990
+ "ty.toml",
3991
+ "requirements.txt",
3992
+ "setup.py",
3993
+ "setup.cfg",
3994
+ "Pipfile",
3995
+ "pyrightconfig.json",
3996
+ "ruff.toml",
3997
+ ".ruff.toml"
3998
+ ],
3999
+ binDirs: [
4000
+ join4(".venv", "bin"),
4001
+ join4(".venv", "Scripts"),
4002
+ join4("venv", "bin"),
4003
+ join4("venv", "Scripts"),
4004
+ join4(".env", "bin"),
4005
+ join4(".env", "Scripts")
4006
+ ]
4007
+ },
4008
+ {
4009
+ markers: ["Gemfile", "Gemfile.lock"],
4010
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4011
+ },
4012
+ {
4013
+ markers: ["go.mod", "go.sum", "go.work"],
4014
+ binDirs: ["bin"]
4015
+ }
4016
+ ];
4017
+ var resolutionCache = new Map;
4018
+ var probeCount = 0;
4019
+ function probe(path) {
4020
+ probeCount += 1;
4021
+ return existsSync9(path);
4022
+ }
4023
+ function executableSuffixes(platform, pathExt) {
4024
+ if (platform !== "win32")
4025
+ return [""];
4026
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4027
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4028
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4029
+ }
4030
+ function probeWithSuffixes(directory, command, suffixes) {
4031
+ for (const suffix of suffixes) {
4032
+ const candidate = join4(directory, command + suffix);
4033
+ if (probe(candidate))
4034
+ return candidate;
3910
4035
  }
3911
- const isWindows = process.platform === "win32";
3912
- let exts = [""];
3913
- if (isWindows) {
3914
- const pathExt = process.env["PATHEXT"] ?? "";
3915
- if (pathExt) {
3916
- const systemExts = pathExt.split(";").filter(Boolean);
3917
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3918
- } else {
3919
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4036
+ return null;
4037
+ }
4038
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4039
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4040
+ let current = resolve7(workingDirectory);
4041
+ while (true) {
4042
+ for (const rule of LOCAL_BIN_RULES) {
4043
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4044
+ continue;
4045
+ for (const binDir of rule.binDirs) {
4046
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4047
+ if (found !== null)
4048
+ return found;
4049
+ }
3920
4050
  }
4051
+ if (probe(join4(current, ".git")))
4052
+ return null;
4053
+ if (boundary !== undefined && current === boundary)
4054
+ return null;
4055
+ const parent = dirname7(current);
4056
+ if (parent === current)
4057
+ return null;
4058
+ current = parent;
3921
4059
  }
3922
- let pathEnv = process.env["PATH"] ?? "";
3923
- if (isWindows && !pathEnv) {
4060
+ }
4061
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4062
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4063
+ if (platform === "win32" && !pathEnv) {
3924
4064
  pathEnv = process.env["Path"] ?? "";
3925
4065
  }
3926
- const paths = pathEnv.split(delimiter3);
3927
- for (const p of paths) {
3928
- for (const suffix of exts) {
3929
- if (existsSync8(join3(p, cmd + suffix))) {
3930
- return true;
3931
- }
3932
- }
4066
+ for (const entry of pathEnv.split(delimiter3)) {
4067
+ if (entry.length === 0)
4068
+ continue;
4069
+ const found = probeWithSuffixes(entry, command, suffixes);
4070
+ if (found !== null)
4071
+ return found;
3933
4072
  }
3934
- if (cmd === "node")
3935
- return true;
3936
- return false;
4073
+ return null;
4074
+ }
4075
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4076
+ if (command.length === 0)
4077
+ return null;
4078
+ const [cmd] = command;
4079
+ if (cmd === undefined || cmd.length === 0)
4080
+ return null;
4081
+ const platform = options.platform ?? process.platform;
4082
+ const suffixes = executableSuffixes(platform, options.pathExt);
4083
+ if (cmd.includes("/") || cmd.includes("\\")) {
4084
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4085
+ return probe(explicit) ? explicit : null;
4086
+ }
4087
+ const cacheKey = JSON.stringify([
4088
+ workingDirectory ?? "",
4089
+ cmd,
4090
+ platform,
4091
+ options.stopAt ?? "",
4092
+ options.pathExt ?? "",
4093
+ options.pathEnv ?? process.env["PATH"] ?? ""
4094
+ ]);
4095
+ const cached = resolutionCache.get(cacheKey);
4096
+ if (cached !== undefined)
4097
+ return cached;
4098
+ let resolved = null;
4099
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4100
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4101
+ }
4102
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4103
+ if (resolved === null && cmd === "node")
4104
+ resolved = cmd;
4105
+ resolutionCache.set(cacheKey, resolved);
4106
+ return resolved;
4107
+ }
4108
+ function isServerInstalled(command, workingDirectory, options = {}) {
4109
+ if (command.length === 0)
4110
+ return false;
4111
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3937
4112
  }
3938
4113
 
3939
4114
  // ../lsp-core/src/lsp/server-resolution.ts
4115
+ function withResolvedCommand(command, binaryPath) {
4116
+ return [binaryPath, ...command.slice(1)];
4117
+ }
3940
4118
  function findServerForExtension(ext) {
3941
4119
  const servers = getMergedServers();
4120
+ const workingDirectory = contextCwd();
3942
4121
  for (const server2 of servers) {
3943
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4122
+ if (!server2.extensions.includes(ext))
4123
+ continue;
4124
+ const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4125
+ if (binaryPath !== null) {
3944
4126
  const resolvedServer = {
3945
4127
  id: server2.id,
3946
- command: server2.command,
4128
+ command: withResolvedCommand(server2.command, binaryPath),
3947
4129
  extensions: server2.extensions,
3948
4130
  priority: server2.priority
3949
4131
  };
@@ -3990,6 +4172,7 @@ function findServerForExtension(ext) {
3990
4172
  function getAllServers() {
3991
4173
  const servers = getMergedServers();
3992
4174
  const disabled = getDisabledServerIds();
4175
+ const workingDirectory = contextCwd();
3993
4176
  const result = [];
3994
4177
  const seen = new Set;
3995
4178
  for (const server2 of servers) {
@@ -3997,7 +4180,7 @@ function getAllServers() {
3997
4180
  continue;
3998
4181
  result.push({
3999
4182
  id: server2.id,
4000
- installed: isServerInstalled(server2.command),
4183
+ installed: isServerInstalled(server2.command, workingDirectory),
4001
4184
  extensions: server2.extensions,
4002
4185
  disabled: false,
4003
4186
  source: server2.source,
@@ -4011,7 +4194,7 @@ function getAllServers() {
4011
4194
  const builtin = BUILTIN_SERVERS[id];
4012
4195
  result.push({
4013
4196
  id,
4014
- installed: builtin ? isServerInstalled(builtin.command) : false,
4197
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4015
4198
  extensions: builtin?.extensions ?? [],
4016
4199
  disabled: true,
4017
4200
  source: "disabled",
@@ -4022,7 +4205,6 @@ function getAllServers() {
4022
4205
  }
4023
4206
 
4024
4207
  // ../lsp-core/src/lsp/client-wrapper.ts
4025
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4026
4208
  function isDirectoryPath(filePath) {
4027
4209
  try {
4028
4210
  return statSync3(filePath).isDirectory();
@@ -4031,32 +4213,85 @@ function isDirectoryPath(filePath) {
4031
4213
  }
4032
4214
  }
4033
4215
  function findWorkspaceRoot(filePath) {
4034
- const abs = resolvePathInsideContext(filePath);
4216
+ const cwd = contextCwd();
4217
+ const abs = resolveReadablePathInsideContext(filePath);
4035
4218
  let dir = abs;
4036
4219
  if (!isDirectoryPath(dir)) {
4037
- dir = dirname6(dir);
4038
- }
4039
- let prevDir = "";
4040
- while (dir !== prevDir) {
4041
- for (const marker of WORKSPACE_MARKERS) {
4042
- if (existsSync9(join4(dir, marker))) {
4043
- return dir;
4220
+ dir = dirname8(dir);
4221
+ }
4222
+ if (!isPathInside(cwd, abs))
4223
+ return findWorkspaceRootOutsideContext(dir);
4224
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4225
+ while (isPathInside(cwd, dir)) {
4226
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4227
+ if (canonicalDir !== undefined) {
4228
+ for (const marker of WORKSPACE_MARKERS) {
4229
+ if (existsSync10(join5(dir, marker))) {
4230
+ return canonicalDir;
4231
+ }
4044
4232
  }
4045
4233
  }
4046
- prevDir = dir;
4047
- dir = dirname6(dir);
4234
+ if (dir === cwd)
4235
+ break;
4236
+ dir = dirname8(dir);
4048
4237
  }
4049
- return dirname6(abs);
4238
+ return fallbackRoot;
4239
+ }
4240
+ function resolveReadablePathInsideContext(filePath) {
4241
+ const cwd = contextCwd();
4242
+ const abs = resolve8(cwd, filePath);
4243
+ if (isPathInside(cwd, abs))
4244
+ return abs;
4245
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4246
+ if (rebased !== undefined)
4247
+ return rebased;
4248
+ return canonicalizeExistingOrNearestAncestor(abs);
4050
4249
  }
4051
4250
  function resolvePathInsideContext(filePath) {
4052
4251
  const cwd = contextCwd();
4053
- const abs = resolve7(cwd, filePath);
4252
+ const abs = resolveReadablePathInsideContext(filePath);
4054
4253
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4055
4254
  if (!isPathInside(cwd, canonical)) {
4056
4255
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4057
4256
  }
4058
4257
  return canonical;
4059
4258
  }
4259
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4260
+ let current = path;
4261
+ const suffix = [];
4262
+ while (true) {
4263
+ if (existsSync10(current)) {
4264
+ const canonical = realpathSync5(current);
4265
+ if (isPathInside(cwd, canonical))
4266
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4267
+ }
4268
+ const parent = dirname8(current);
4269
+ if (parent === current)
4270
+ return;
4271
+ suffix.unshift(basename3(current));
4272
+ current = parent;
4273
+ }
4274
+ }
4275
+ function existingDirectoryInsideContext(directory, cwd) {
4276
+ if (!existsSync10(directory))
4277
+ return;
4278
+ const canonical = realpathSync5(directory);
4279
+ if (!statSync3(canonical).isDirectory())
4280
+ return;
4281
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4282
+ }
4283
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4284
+ let current = directory;
4285
+ while (isPathInside(cwd, current)) {
4286
+ const canonical = existingDirectoryInsideContext(current, cwd);
4287
+ if (canonical !== undefined)
4288
+ return canonical;
4289
+ if (current === cwd)
4290
+ return;
4291
+ current = dirname8(current);
4292
+ }
4293
+ return;
4294
+ }
4060
4295
  function formatServerLookupError(result) {
4061
4296
  if (result.status === "not_installed") {
4062
4297
  return formatNotInstalled(result);
@@ -4080,6 +4315,19 @@ function formatServerLookupError(result) {
4080
4315
  ].join(`
4081
4316
  `);
4082
4317
  }
4318
+ function formatInstallOptions(serverId, installHint) {
4319
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4320
+ if (localHint === undefined) {
4321
+ return ["To install, run:", ` ${installHint}`];
4322
+ }
4323
+ return [
4324
+ "To install in THIS repository (preferred — no global install needed):",
4325
+ ` ${localHint}`,
4326
+ "",
4327
+ "Or install it globally:",
4328
+ ` ${installHint}`
4329
+ ];
4330
+ }
4083
4331
  function formatNotInstalled(result) {
4084
4332
  const { server: server2, installHint } = result;
4085
4333
  const extensions = server2.extensions.join(", ");
@@ -4094,19 +4342,19 @@ function formatNotInstalled(result) {
4094
4342
  `Command not found: ${server2.command[0]}`,
4095
4343
  ""
4096
4344
  ];
4345
+ const installOptions = formatInstallOptions(server2.id, installHint);
4097
4346
  if (decision === "allowed") {
4098
4347
  return [
4099
4348
  ...header,
4100
4349
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4101
- ` ${installHint}`
4350
+ ...installOptions.slice(1)
4102
4351
  ].join(`
4103
4352
  `);
4104
4353
  }
4105
4354
  if (!context.capabilities.installDecisionTool) {
4106
4355
  return [
4107
4356
  ...header,
4108
- "To install, run:",
4109
- ` ${installHint}`,
4357
+ ...installOptions,
4110
4358
  "",
4111
4359
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4112
4360
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4115,8 +4363,7 @@ function formatNotInstalled(result) {
4115
4363
  }
4116
4364
  return [
4117
4365
  ...header,
4118
- "To install, run:",
4119
- ` ${installHint}`,
4366
+ ...installOptions,
4120
4367
  "",
4121
4368
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4122
4369
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4127,7 +4374,7 @@ function formatNotInstalled(result) {
4127
4374
  ].join(`
4128
4375
  `);
4129
4376
  }
4130
- var READ_ONLY_RETRY_TOOLS = new Set([
4377
+ var READ_ONLY_TOOLS = new Set([
4131
4378
  "diagnostics",
4132
4379
  "definition",
4133
4380
  "references",
@@ -4136,7 +4383,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4136
4383
  "prepareRename"
4137
4384
  ]);
4138
4385
  async function withLspClient(filePath, fn, toolName, options = {}) {
4139
- const absPath = resolvePathInsideContext(filePath);
4386
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4140
4387
  if (isDirectoryPath(absPath)) {
4141
4388
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4142
4389
  }
@@ -4151,9 +4398,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4151
4398
  const acquireAndCall = async (allowRetry) => {
4152
4399
  const client = await manager2.getClient(root, server2, options.signal);
4153
4400
  try {
4154
- return await fn(client, root);
4401
+ return await fn(client, root, absPath);
4155
4402
  } catch (err) {
4156
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4403
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4157
4404
  manager2.invalidateClient(root, server2.id, client);
4158
4405
  return acquireAndCall(false);
4159
4406
  }
@@ -4171,8 +4418,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4171
4418
  }
4172
4419
 
4173
4420
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4174
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4175
- import { join as join5, resolve as resolve8 } from "node:path";
4421
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4422
+ import { join as join6, resolve as resolve9 } from "node:path";
4176
4423
 
4177
4424
  // ../lsp-core/src/lsp/formatters.ts
4178
4425
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4302,7 +4549,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4302
4549
  for (const entry of entries) {
4303
4550
  if (files.length >= maxFiles)
4304
4551
  return;
4305
- const fullPath = join5(currentDir, entry);
4552
+ const fullPath = join6(currentDir, entry);
4306
4553
  let stat;
4307
4554
  try {
4308
4555
  stat = lstatSync4(fullPath);
@@ -4327,8 +4574,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4327
4574
  if (!extension.startsWith(".")) {
4328
4575
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4329
4576
  }
4330
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4331
- if (!existsSync10(absDir)) {
4577
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4578
+ if (!existsSync11(absDir)) {
4332
4579
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4333
4580
  }
4334
4581
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -4415,7 +4662,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4415
4662
 
4416
4663
  // ../lsp-core/src/lsp/infer-extension.ts
4417
4664
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4418
- import { join as join6 } from "node:path";
4665
+ import { join as join7 } from "node:path";
4419
4666
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4420
4667
  var MAX_SCAN_ENTRIES = 500;
4421
4668
  function inferExtensionFromDirectory(directory) {
@@ -4433,7 +4680,7 @@ function inferExtensionFromDirectory(directory) {
4433
4680
  for (const entry of entries) {
4434
4681
  if (scanned >= MAX_SCAN_ENTRIES)
4435
4682
  return;
4436
- const fullPath = join6(dir, entry);
4683
+ const fullPath = join7(dir, entry);
4437
4684
  let stat;
4438
4685
  try {
4439
4686
  stat = lstatSync5(fullPath);
@@ -4608,7 +4855,7 @@ async function executeLspDiagnostics(params, signal) {
4608
4855
  const filePath = requireString(params, "filePath");
4609
4856
  const severity = severityFilter(params);
4610
4857
  try {
4611
- const absPath = resolvePathInsideContext(filePath);
4858
+ const absPath = resolveReadablePathInsideContext(filePath);
4612
4859
  if (isDirectoryPath(absPath)) {
4613
4860
  const extension = inferExtensionFromDirectory(absPath);
4614
4861
  if (!extension) {
@@ -4637,7 +4884,7 @@ async function executeLspDiagnostics(params, signal) {
4637
4884
  };
4638
4885
  return text(output2.output, details2);
4639
4886
  }
4640
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
4887
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4641
4888
  if (result.transientError) {
4642
4889
  const message = result.transientError.message;
4643
4890
  const details2 = {
@@ -4684,6 +4931,96 @@ async function executeLspDiagnostics(params, signal) {
4684
4931
  throw error;
4685
4932
  }
4686
4933
  }
4934
+ // ../lsp-core/src/lsp/format-document.ts
4935
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
4936
+ var DEFAULT_FORMATTING_OPTIONS = {
4937
+ tabSize: 4,
4938
+ insertSpaces: false,
4939
+ trimTrailingWhitespace: true,
4940
+ insertFinalNewline: true,
4941
+ trimFinalNewlines: true
4942
+ };
4943
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
4944
+ async function formatDocumentWithClient(client, filePath, options = {}) {
4945
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
4946
+ if (edits === null)
4947
+ return { status: "unavailable", reason: "capability_not_advertised" };
4948
+ if (edits.length === 0)
4949
+ return UNCHANGED;
4950
+ const before = readFileSync5(filePath, "utf-8");
4951
+ const normalized = normalizeTextEdits(before, edits, 0);
4952
+ if (normalized.text === before)
4953
+ return UNCHANGED;
4954
+ writeAtomically(filePath, normalized.text);
4955
+ await client.openFile(filePath);
4956
+ return {
4957
+ status: "formatted",
4958
+ ...lineDelta(normalized.edits)
4959
+ };
4960
+ }
4961
+ function lineDelta(edits) {
4962
+ let linesAdded = 0;
4963
+ let linesRemoved = 0;
4964
+ for (const edit of edits) {
4965
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
4966
+ linesAdded += edit.newText.split(`
4967
+ `).length;
4968
+ }
4969
+ return { linesAdded, linesRemoved };
4970
+ }
4971
+ function writeAtomically(filePath, content) {
4972
+ const tempPath = `${filePath}.omo-format.tmp`;
4973
+ writeFileSync3(tempPath, content, "utf-8");
4974
+ try {
4975
+ renameSync3(tempPath, filePath);
4976
+ } catch (error) {
4977
+ try {
4978
+ unlinkSync(tempPath);
4979
+ } catch {}
4980
+ throw error;
4981
+ }
4982
+ }
4983
+
4984
+ // ../lsp-core/src/tools/format.ts
4985
+ async function executeLspFormat(params, signal) {
4986
+ const filePath = requireString(params, "filePath");
4987
+ try {
4988
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
4989
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
4990
+ } catch (error) {
4991
+ const missingDependency = missingDependencyResult(error, {
4992
+ filePath,
4993
+ status: "unavailable",
4994
+ reason: "server_unavailable",
4995
+ linesAdded: 0,
4996
+ linesRemoved: 0
4997
+ });
4998
+ if (missingDependency)
4999
+ return missingDependency;
5000
+ throw error;
5001
+ }
5002
+ }
5003
+ function formatDetails(filePath, result) {
5004
+ if (result.status === "unavailable") {
5005
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5006
+ }
5007
+ return {
5008
+ filePath,
5009
+ status: result.status,
5010
+ linesAdded: result.linesAdded,
5011
+ linesRemoved: result.linesRemoved
5012
+ };
5013
+ }
5014
+ function describeResult(filePath, result) {
5015
+ if (result.status === "unavailable") {
5016
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5017
+ }
5018
+ if (result.status === "unchanged") {
5019
+ return `Already formatted: ${filePath}`;
5020
+ }
5021
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5022
+ }
5023
+
4687
5024
  // ../lsp-core/src/tools/install-decision.ts
4688
5025
  async function executeLspInstallDecision(params) {
4689
5026
  const serverId = requireString(params, "server_id");
@@ -4712,7 +5049,7 @@ async function executeLspGotoDefinition(params, signal) {
4712
5049
  const line = requireNumber(params, "line");
4713
5050
  const character = requireNumber(params, "character");
4714
5051
  try {
4715
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5052
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4716
5053
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4717
5054
  const details = { filePath, line, character, locations };
4718
5055
  if (locations.length === 0)
@@ -4737,7 +5074,7 @@ async function executeLspFindReferences(params, signal) {
4737
5074
  const character = requireNumber(params, "character");
4738
5075
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4739
5076
  try {
4740
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5077
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4741
5078
  const references = Array.isArray(result) ? result : [];
4742
5079
  const total = references.length;
4743
5080
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4779,7 +5116,7 @@ async function executeLspPrepareRename(params, signal) {
4779
5116
  const line = requireNumber(params, "line");
4780
5117
  const character = requireNumber(params, "character");
4781
5118
  try {
4782
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5119
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4783
5120
  const details = { filePath, line, character, result };
4784
5121
  return text(formatPrepareRenameResult(result), details);
4785
5122
  } catch (error) {
@@ -4800,7 +5137,7 @@ async function executeLspRename(params, signal) {
4800
5137
  const character = requireNumber(params, "character");
4801
5138
  const newName = requireString(params, "newName");
4802
5139
  try {
4803
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5140
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4804
5141
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4805
5142
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4806
5143
  } catch (error) {
@@ -4880,7 +5217,7 @@ async function executeLspSymbols(params, signal) {
4880
5217
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4881
5218
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
4882
5219
  }
4883
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5220
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4884
5221
  return formatSymbolsResult(filePath, scope, symbols, limit);
4885
5222
  } catch (error) {
4886
5223
  const query = optionalString(params, "query");
@@ -5016,6 +5353,16 @@ var LSP_MCP_TOOLS = [
5016
5353
  }, ["filePath", "line", "character", "newName"]),
5017
5354
  execute: executeLspRename
5018
5355
  },
5356
+ {
5357
+ name: "format",
5358
+ aliases: ["lsp_format"],
5359
+ title: "LSP Format",
5360
+ description: "Format a source file with its language server and write the returned edits to disk.",
5361
+ inputSchema: objectSchema({
5362
+ filePath: { type: "string", description: "Source file path to format." }
5363
+ }, ["filePath"]),
5364
+ execute: executeLspFormat
5365
+ },
5019
5366
  {
5020
5367
  name: "install_decision",
5021
5368
  aliases: ["lsp_install_decision"],