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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (639) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  4. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  5. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  6. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  7. package/.opencode/command/publish.md +44 -16
  8. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  9. package/README.ja.md +25 -21
  10. package/README.ko.md +25 -21
  11. package/README.md +38 -23
  12. package/README.ru.md +24 -20
  13. package/README.zh-cn.md +25 -21
  14. package/dist/agents/atlas/agent.d.ts +0 -1
  15. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  16. package/dist/agents/sisyphus/index.d.ts +2 -0
  17. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  18. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  19. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  22. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  23. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  24. package/dist/cli/index.js +22601 -20302
  25. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  26. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  27. package/dist/cli/runtime-commands.d.ts +1 -1
  28. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  29. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  30. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  31. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  32. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  34. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  35. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  36. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  37. package/dist/cli-node/index.js +22219 -19897
  38. package/dist/config/schema/background-task.d.ts +1 -0
  39. package/dist/config/schema/commands.d.ts +1 -1
  40. package/dist/config/schema/hooks.d.ts +1 -1
  41. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -1
  42. package/dist/config/schema/ulw-execute.d.ts +5 -0
  43. package/dist/config/validate.d.ts +2 -0
  44. package/dist/create-hooks.d.ts +3 -1
  45. package/dist/features/background-agent/constants.d.ts +0 -7
  46. package/dist/features/background-agent/manager.d.ts +2 -1
  47. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  48. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  49. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  50. package/dist/features/btw-side/context-injector.d.ts +15 -0
  51. package/dist/features/btw-side/index.d.ts +8 -0
  52. package/dist/features/btw-side/metadata.d.ts +15 -0
  53. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  54. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  55. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  56. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  57. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  58. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  59. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  60. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  61. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  62. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  63. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  64. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  65. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  66. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  67. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  68. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  69. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  70. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  71. package/dist/features/builtin-commands/types.d.ts +1 -1
  72. package/dist/features/opengateway-provider/index.d.ts +13 -0
  73. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  74. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
  75. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  76. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  77. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  78. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  79. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  80. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  81. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  82. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  83. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  84. package/dist/hooks/atlas/types.d.ts +1 -0
  85. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  86. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  87. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  88. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  89. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  90. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  91. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  92. package/dist/hooks/index.d.ts +1 -1
  93. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  94. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  95. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  96. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  97. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  98. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  99. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  100. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  101. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  102. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  103. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  104. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  105. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  106. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  107. package/dist/index.js +12989 -7152
  108. package/dist/oh-my-opencode.schema.json +20 -2
  109. package/dist/plugin/chat-message/types.d.ts +3 -3
  110. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  111. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  112. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  113. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  114. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  115. package/dist/plugin/messages-transform.d.ts +1 -0
  116. package/dist/plugin-dispose.d.ts +3 -0
  117. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  118. package/dist/shared/index.d.ts +2 -0
  119. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  120. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  121. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  122. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  123. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  124. package/dist/shared/shell-env.d.ts +1 -1
  125. package/dist/skills/ast-grep/AGENTS.md +51 -0
  126. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  127. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  128. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  129. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  130. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  131. package/dist/skills/data-scientist/SKILL.md +99 -239
  132. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  133. package/dist/skills/data-scientist/references/placement.md +74 -0
  134. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  135. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  136. package/dist/skills/data-scientist/references/visualization.md +64 -0
  137. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  138. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  139. package/dist/skills/debugging/SKILL.md +2 -0
  140. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  141. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  142. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  143. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  144. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  145. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  146. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  147. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  148. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  149. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  150. package/dist/skills/debugging/references/tools/dap.md +103 -0
  151. package/dist/skills/debugging/references/tools/frida.md +193 -0
  152. package/dist/skills/frontend/SKILL.md +11 -7
  153. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  154. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  155. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  156. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  157. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  158. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  159. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  160. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  161. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  162. package/dist/skills/review-work/SKILL.md +3 -3
  163. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  164. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  165. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  166. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  167. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  168. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  169. package/dist/skills/ulw-plan/SKILL.md +6 -6
  170. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  171. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  172. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  173. package/dist/skills/ulw-research/SKILL.md +4 -2
  174. package/dist/skills/visual-qa/AGENTS.md +58 -0
  175. package/dist/skills/visual-qa/SKILL.md +3 -2
  176. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  177. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  178. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  179. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  180. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  181. package/dist/tools/delegate-task/types.d.ts +4 -0
  182. package/dist/tui.d.ts +12 -0
  183. package/dist/tui.js +11522 -11501
  184. package/package.json +42 -36
  185. package/packages/git-bash-mcp/dist/cli.js +6 -1
  186. package/packages/git-bash-mcp/package.json +1 -1
  187. package/packages/lsp-core/src/index.ts +1 -0
  188. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  189. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  190. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  191. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
  192. package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
  193. package/packages/lsp-core/src/lsp/client.ts +26 -0
  194. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  195. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  196. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  197. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  198. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  199. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  200. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  201. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  202. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  203. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  204. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  205. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  206. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  207. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  208. package/packages/lsp-core/src/lsp/transport.ts +9 -0
  209. package/packages/lsp-core/src/lsp/types.ts +8 -0
  210. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  211. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  212. package/packages/lsp-core/src/mcp.ts +3 -0
  213. package/packages/lsp-core/src/request-context.test.ts +29 -0
  214. package/packages/lsp-core/src/request-context.ts +1 -1
  215. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  216. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  217. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  218. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  219. package/packages/lsp-core/src/tools/format.ts +56 -0
  220. package/packages/lsp-core/src/tools/index.ts +1 -0
  221. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  222. package/packages/lsp-core/src/tools/rename.ts +4 -2
  223. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  224. package/packages/lsp-core/src/tools/types.ts +10 -0
  225. package/packages/lsp-daemon/dist/cli.js +752 -307
  226. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  227. package/packages/lsp-daemon/dist/client.js +712 -264
  228. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  229. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  230. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  231. package/packages/lsp-daemon/dist/index.js +716 -273
  232. package/packages/lsp-daemon/dist/proxy.js +3 -0
  233. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  234. package/packages/lsp-daemon/package.json +1 -1
  235. package/packages/lsp-tools-mcp/dist/cli.js +671 -228
  236. package/packages/lsp-tools-mcp/dist/lsp/manager.js +207 -103
  237. package/packages/lsp-tools-mcp/dist/mcp.js +673 -230
  238. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  239. package/packages/lsp-tools-mcp/dist/tools.js +677 -238
  240. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  241. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  242. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  243. package/packages/omo-codex/plugin/README.md +1 -1
  244. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
  245. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  246. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  247. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  248. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +323 -117
  249. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -85
  250. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  251. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  252. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
  253. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  254. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
  255. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  256. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  257. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  258. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  259. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  260. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  261. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  262. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  263. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  264. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  265. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  266. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  267. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  268. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  269. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  270. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  271. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  272. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  273. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  274. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  275. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  276. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  277. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +702 -278
  278. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  279. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  280. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  281. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  282. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  283. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  284. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  285. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  286. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  287. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  288. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  289. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  290. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  291. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  292. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  293. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  294. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  295. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  296. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  297. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  298. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  299. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  300. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  301. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  302. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  303. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  304. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  305. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  306. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  307. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  308. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  309. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  310. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  311. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  312. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  313. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  314. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  315. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  316. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  317. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  318. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  319. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  320. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  321. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  322. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  323. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  324. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  325. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  326. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  327. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  328. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  329. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  330. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  331. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  332. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  333. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  334. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  335. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  336. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  337. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  338. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  339. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  340. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  341. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  342. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  343. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  344. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  345. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  346. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  347. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  348. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  349. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  350. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  351. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  352. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  353. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  354. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  355. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  356. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  357. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  358. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  359. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  360. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +17 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  362. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  363. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +11 -1
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +124 -68
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +9 -6
  371. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  372. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  373. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  374. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +7 -10
  375. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
  376. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  377. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
  378. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
  379. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  380. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  381. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  382. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  383. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  384. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -0
  385. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
  386. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
  387. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  388. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
  389. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  390. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  391. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  392. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
  393. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
  394. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  395. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -0
  396. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  397. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +44 -1
  398. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  399. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  400. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +27 -2
  401. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  402. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  403. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  404. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  405. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  406. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +45 -2
  407. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
  408. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  409. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  410. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  411. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  412. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  413. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  414. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  415. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  416. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  417. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  418. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  419. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  420. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  421. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  422. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  423. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  424. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  425. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  426. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  427. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  428. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  429. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  430. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  432. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  433. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  434. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  435. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  436. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  437. package/packages/omo-codex/plugin/package-lock.json +681 -395
  438. package/packages/omo-codex/plugin/package.json +2 -2
  439. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  440. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  441. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  442. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  443. package/packages/omo-codex/plugin/shared/package.json +3 -4
  444. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  445. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  446. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  447. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  448. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  449. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  450. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  451. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  452. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  453. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  454. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  455. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  456. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  457. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  458. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  459. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  460. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  461. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  462. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  463. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  464. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  465. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  466. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  467. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  468. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  469. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  470. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  471. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  472. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  473. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  474. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  475. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  476. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  477. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  478. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  479. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  480. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  481. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  482. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  483. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  484. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  485. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  486. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  487. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  488. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  489. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  490. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  491. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  492. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  493. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  494. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  495. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  496. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  497. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  498. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  499. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  500. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  501. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  502. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  503. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  504. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  505. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  506. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  507. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
  508. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  509. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  510. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  511. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  512. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  513. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  514. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  515. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  516. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  517. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  518. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  519. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  520. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  521. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  522. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  523. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  524. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  525. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  526. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  527. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
  528. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  529. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  530. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  531. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  532. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  533. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  534. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  535. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  536. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  537. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  538. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  539. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  540. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  541. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  542. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  543. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  544. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  545. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  546. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  547. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  548. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  549. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  550. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  551. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  552. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  553. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  554. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  555. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  556. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  557. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  558. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  559. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  560. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  561. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  562. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  563. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  564. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  565. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  566. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  567. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  568. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  569. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  570. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  571. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  572. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  573. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  574. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  575. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  576. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  577. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  578. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  579. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  580. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  581. package/script/qa/xterm-live-terminal.mjs +18 -2
  582. package/dist/config/schema/start-work.d.ts +0 -5
  583. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  584. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  585. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  586. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  587. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  588. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  589. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  590. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  591. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  592. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  593. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  594. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  595. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  596. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  597. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  598. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  599. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  600. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  601. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  602. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  603. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  604. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  605. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  606. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  607. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  608. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  609. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  610. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  611. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  612. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  613. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  614. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  615. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  616. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  617. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  618. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  619. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  620. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  621. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  622. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  623. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  624. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  625. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  626. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  627. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  628. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  629. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  630. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  631. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  632. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  633. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  634. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  635. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  636. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  637. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  638. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  639. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,45 +1,218 @@
1
1
  import { existsSync } from "node:fs";
2
- import { delimiter, join } from "node:path";
2
+ import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
3
3
 
4
- export function isServerInstalled(command: string[], _workingDirectory?: string): boolean {
5
- if (command.length === 0) return false;
4
+ /**
5
+ * Project markers that authorize probing a set of repo-local binary directories.
6
+ *
7
+ * A local bin directory is only trusted when the sibling marker proves the directory
8
+ * belongs to a project of that ecosystem. An unmarked `node_modules/.bin` is ignored so
9
+ * that a stray directory cannot inject an executable into the resolution order.
10
+ */
11
+ interface LocalBinRule {
12
+ readonly markers: readonly string[];
13
+ readonly binDirs: readonly string[];
14
+ }
6
15
 
7
- const [cmd] = command;
8
- if (!cmd) return false;
16
+ const LOCAL_BIN_RULES: readonly LocalBinRule[] = [
17
+ {
18
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
19
+ binDirs: [join("node_modules", ".bin")],
20
+ },
21
+ {
22
+ markers: [
23
+ "pyproject.toml",
24
+ "ty.toml",
25
+ "requirements.txt",
26
+ "setup.py",
27
+ "setup.cfg",
28
+ "Pipfile",
29
+ "pyrightconfig.json",
30
+ "ruff.toml",
31
+ ".ruff.toml",
32
+ ],
33
+ binDirs: [
34
+ join(".venv", "bin"),
35
+ join(".venv", "Scripts"),
36
+ join("venv", "bin"),
37
+ join("venv", "Scripts"),
38
+ join(".env", "bin"),
39
+ join(".env", "Scripts"),
40
+ ],
41
+ },
42
+ {
43
+ markers: ["Gemfile", "Gemfile.lock"],
44
+ binDirs: [join("vendor", "bundle", "bin"), "bin"],
45
+ },
46
+ {
47
+ markers: ["go.mod", "go.sum", "go.work"],
48
+ binDirs: ["bin"],
49
+ },
50
+ ];
9
51
 
10
- if (cmd.includes("/") || cmd.includes("\\")) {
11
- if (existsSync(cmd)) return true;
52
+ export interface ResolveServerBinaryOptions {
53
+ /**
54
+ * Upward walk boundary. The walk never ascends above this directory, which lets callers
55
+ * confine resolution to a trusted request cwd.
56
+ */
57
+ readonly stopAt?: string;
58
+ readonly platform?: NodeJS.Platform;
59
+ readonly pathExt?: string;
60
+ readonly pathEnv?: string;
61
+ }
62
+
63
+ const resolutionCache = new Map<string, string | null>();
64
+ let probeCount = 0;
65
+
66
+ /** Test seam: clears the per-process resolution cache. */
67
+ export function __resetServerBinaryResolutionCacheForTests(): void {
68
+ resolutionCache.clear();
69
+ probeCount = 0;
70
+ }
71
+
72
+ /** Test seam: counts filesystem probes so cache hits are observable. */
73
+ export function __serverBinaryProbeCountForTests(): number {
74
+ return probeCount;
75
+ }
76
+
77
+ function probe(path: string): boolean {
78
+ probeCount += 1;
79
+ return existsSync(path);
80
+ }
81
+
82
+ function executableSuffixes(platform: NodeJS.Platform, pathExt: string | undefined): readonly string[] {
83
+ if (platform !== "win32") return [""];
84
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
85
+ // PATHEXT is conventionally uppercase, but the on-disk shims npm/bun write are lowercase.
86
+ // Probe lowercase first so the returned path matches the real filename on case-sensitive
87
+ // filesystems; the resolved path is spawned, so its casing has to be exact.
88
+ const systemExts = configured
89
+ .split(";")
90
+ .filter((entry) => entry.length > 0)
91
+ .map((entry) => entry.toLowerCase());
92
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
93
+ }
94
+
95
+ function probeWithSuffixes(directory: string, command: string, suffixes: readonly string[]): string | null {
96
+ for (const suffix of suffixes) {
97
+ const candidate = join(directory, command + suffix);
98
+ if (probe(candidate)) return candidate;
12
99
  }
100
+ return null;
101
+ }
13
102
 
14
- const isWindows = process.platform === "win32";
103
+ function resolveLocal(
104
+ command: string,
105
+ workingDirectory: string,
106
+ suffixes: readonly string[],
107
+ stopAt: string | undefined,
108
+ ): string | null {
109
+ const boundary = stopAt === undefined ? undefined : resolve(stopAt);
110
+ let current = resolve(workingDirectory);
15
111
 
16
- let exts = [""];
17
- if (isWindows) {
18
- const pathExt = process.env["PATHEXT"] ?? "";
19
- if (pathExt) {
20
- const systemExts = pathExt.split(";").filter(Boolean);
21
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
22
- } else {
23
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
112
+ while (true) {
113
+ for (const rule of LOCAL_BIN_RULES) {
114
+ if (!rule.markers.some((marker) => probe(join(current, marker)))) continue;
115
+ for (const binDir of rule.binDirs) {
116
+ const found = probeWithSuffixes(join(current, binDir), command, suffixes);
117
+ if (found !== null) return found;
118
+ }
24
119
  }
120
+
121
+ // A repository root ends the walk: tooling above it belongs to a different project.
122
+ if (probe(join(current, ".git"))) return null;
123
+ if (boundary !== undefined && current === boundary) return null;
124
+
125
+ const parent = dirname(current);
126
+ if (parent === current) return null;
127
+ current = parent;
25
128
  }
129
+ }
26
130
 
27
- let pathEnv = process.env["PATH"] ?? "";
28
- if (isWindows && !pathEnv) {
131
+ function resolveFromPath(
132
+ command: string,
133
+ suffixes: readonly string[],
134
+ platform: NodeJS.Platform,
135
+ pathEnvOverride: string | undefined,
136
+ ): string | null {
137
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
138
+ if (platform === "win32" && !pathEnv) {
29
139
  pathEnv = process.env["Path"] ?? "";
30
140
  }
31
141
 
32
- const paths = pathEnv.split(delimiter);
142
+ for (const entry of pathEnv.split(delimiter)) {
143
+ if (entry.length === 0) continue;
144
+ const found = probeWithSuffixes(entry, command, suffixes);
145
+ if (found !== null) return found;
146
+ }
147
+ return null;
148
+ }
33
149
 
34
- for (const p of paths) {
35
- for (const suffix of exts) {
36
- if (existsSync(join(p, cmd + suffix))) {
37
- return true;
38
- }
39
- }
150
+ /**
151
+ * Resolves the absolute path of an LSP server binary.
152
+ *
153
+ * Probing order:
154
+ * 1. a path-shaped command is validated as-is,
155
+ * 2. marker-gated repo-local bin directories, walking up from `workingDirectory`,
156
+ * 3. `PATH` (including Windows executable suffixes),
157
+ * 4. `null` when nothing matches.
158
+ *
159
+ * Results are cached per process, keyed by working directory and command.
160
+ */
161
+ export function resolveServerBinary(
162
+ command: string[],
163
+ workingDirectory?: string,
164
+ options: ResolveServerBinaryOptions = {},
165
+ ): string | null {
166
+ if (command.length === 0) return null;
167
+ const [cmd] = command;
168
+ if (cmd === undefined || cmd.length === 0) return null;
169
+
170
+ const platform = options.platform ?? process.platform;
171
+ const suffixes = executableSuffixes(platform, options.pathExt);
172
+
173
+ if (cmd.includes("/") || cmd.includes("\\")) {
174
+ const explicit = isAbsolute(cmd) ? cmd : resolve(workingDirectory ?? process.cwd(), cmd);
175
+ return probe(explicit) ? explicit : null;
176
+ }
177
+
178
+ const cacheKey = JSON.stringify([
179
+ workingDirectory ?? "",
180
+ cmd,
181
+ platform,
182
+ options.stopAt ?? "",
183
+ options.pathExt ?? "",
184
+ options.pathEnv ?? process.env["PATH"] ?? "",
185
+ ]);
186
+ const cached = resolutionCache.get(cacheKey);
187
+ if (cached !== undefined) return cached;
188
+
189
+ let resolved: string | null = null;
190
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
191
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
40
192
  }
193
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
194
+ // A configured server may be launched through the interpreter itself, e.g.
195
+ // { command: ["node", "my-ls.js"] }. isServerInstalled() has always treated bare `node`
196
+ // as available regardless of PATH, so keep those servers selectable instead of
197
+ // regressing them into a not_installed result. The name is returned unresolved so the
198
+ // spawn still goes through `node`; rewriting it to process.execPath would silently
199
+ // substitute a different interpreter (bun) for the one the config asked for.
200
+ if (resolved === null && cmd === "node") resolved = cmd;
41
201
 
42
- if (cmd === "node") return true;
202
+ resolutionCache.set(cacheKey, resolved);
203
+ return resolved;
204
+ }
43
205
 
44
- return false;
206
+ /**
207
+ * Reports whether an LSP server binary is available.
208
+ *
209
+ * Retained for existing consumers; `resolveServerBinary` is the richer entry point.
210
+ */
211
+ export function isServerInstalled(
212
+ command: string[],
213
+ workingDirectory?: string,
214
+ options: ResolveServerBinaryOptions = {},
215
+ ): boolean {
216
+ if (command.length === 0) return false;
217
+ return resolveServerBinary(command, workingDirectory, options) !== null;
45
218
  }
@@ -0,0 +1,170 @@
1
+ import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
5
+
6
+ import { runWithRequestContext } from "../request-context.js";
7
+ import { formatServerLookupError } from "./client-wrapper.js";
8
+ import { __resetServerBinaryResolutionCacheForTests } from "./server-installation.js";
9
+ import { findServerForExtension } from "./server-resolution.js";
10
+
11
+ const tempDirectories: string[] = [];
12
+ let previousPath: string | undefined;
13
+
14
+ function makeTempRoot(prefix: string): string {
15
+ const root = mkdtempSync(join(tmpdir(), prefix));
16
+ tempDirectories.push(root);
17
+ return root;
18
+ }
19
+
20
+ function writeExecutable(path: string): string {
21
+ mkdirSync(join(path, ".."), { recursive: true });
22
+ writeFileSync(path, "#!/bin/sh\nexit 0\n");
23
+ chmodSync(path, 0o755);
24
+ return path;
25
+ }
26
+
27
+ function contextFor(cwd: string) {
28
+ return {
29
+ cwd,
30
+ projectConfigPaths: [join(cwd, ".codex", "lsp-client.json")],
31
+ userConfigPath: join(cwd, "home-config", "lsp-client.json"),
32
+ installDecisionsPath: join(cwd, "home-config", "lsp-install-decisions.json"),
33
+ capabilities: { installDecisionTool: true },
34
+ } as const;
35
+ }
36
+
37
+ beforeEach(() => {
38
+ previousPath = process.env["PATH"];
39
+ __resetServerBinaryResolutionCacheForTests();
40
+ });
41
+
42
+ afterEach(() => {
43
+ if (previousPath === undefined) delete process.env["PATH"];
44
+ else process.env["PATH"] = previousPath;
45
+ for (const directory of tempDirectories.splice(0)) {
46
+ rmSync(directory, { recursive: true, force: true });
47
+ }
48
+ __resetServerBinaryResolutionCacheForTests();
49
+ });
50
+
51
+ describe("findServerForExtension local binary substitution", () => {
52
+ test("#given a repo-local biome #when looking up a typescript file #then the command spawns the absolute local path", () => {
53
+ // given
54
+ const root = makeTempRoot("lsp-resolution-local-");
55
+ writeFileSync(join(root, "package.json"), "{}\n");
56
+ const binaryPath = writeExecutable(join(root, "node_modules", ".bin", "biome"));
57
+ process.env["PATH"] = join(root, "definitely-empty");
58
+
59
+ // when
60
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".ts"));
61
+
62
+ // then
63
+ expect(result.status).toBe("found");
64
+ if (result.status !== "found") throw new Error("expected a found server");
65
+ expect(result.server.command[0]).toBe(binaryPath);
66
+ expect(result.server.command.slice(1)).toEqual(["lsp-proxy", "--stdio"]);
67
+ });
68
+
69
+ test("#given a PATH-only server #when looking up #then the resolved PATH entry is substituted", () => {
70
+ // given
71
+ const root = makeTempRoot("lsp-resolution-path-root-");
72
+ writeFileSync(join(root, "package.json"), "{}\n");
73
+ const pathDir = makeTempRoot("lsp-resolution-path-");
74
+ const pathBinary = writeExecutable(join(pathDir, "biome"));
75
+ process.env["PATH"] = pathDir;
76
+
77
+ // when
78
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".ts"));
79
+
80
+ // then
81
+ expect(result.status).toBe("found");
82
+ if (result.status !== "found") throw new Error("expected a found server");
83
+ expect(result.server.command[0]).toBe(pathBinary);
84
+ });
85
+
86
+ test("#given no server anywhere #when looking up #then the not_installed result is preserved", () => {
87
+ // given
88
+ const root = makeTempRoot("lsp-resolution-missing-");
89
+ process.env["PATH"] = join(root, "definitely-empty");
90
+
91
+ // when
92
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".ts"));
93
+
94
+ // then
95
+ expect(result.status).toBe("not_installed");
96
+ if (result.status !== "not_installed") throw new Error("expected not_installed");
97
+ expect(result.installHint.length).toBeGreaterThan(0);
98
+ });
99
+
100
+ test("#given an unknown extension #when looking up #then the not_configured result is preserved", () => {
101
+ // given
102
+ const root = makeTempRoot("lsp-resolution-unknown-");
103
+ process.env["PATH"] = join(root, "definitely-empty");
104
+
105
+ // when
106
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".unknown-ext"));
107
+
108
+ // then
109
+ expect(result.status).toBe("not_configured");
110
+ });
111
+ });
112
+
113
+ describe("not-installed message repo-local guidance", () => {
114
+ test("#given a missing biome #when formatting the message #then the repo-local install is suggested before the global hint", () => {
115
+ // given: .css is served by biome alone, so the lookup cannot fall through to typescript
116
+ const root = makeTempRoot("lsp-message-biome-");
117
+ process.env["PATH"] = join(root, "definitely-empty");
118
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".css"));
119
+ if (result.status !== "not_installed") throw new Error("expected not_installed");
120
+ expect(result.server.id).toBe("biome");
121
+
122
+ // when
123
+ const message = runWithRequestContext(contextFor(root), () => formatServerLookupError(result));
124
+
125
+ // then
126
+ expect(message).toContain("bun add -d @biomejs/biome");
127
+ expect(message).toContain("npm install -g @biomejs/biome");
128
+ expect(message.indexOf("bun add -d @biomejs/biome")).toBeLessThan(message.indexOf("npm install -g @biomejs/biome"));
129
+ expect(message).toContain("ACTION REQUIRED");
130
+ expect(message).toContain("NOT INSTALLED");
131
+ });
132
+
133
+ test("#given a server with no repo-local route #when formatting the message #then only the global hint is shown", () => {
134
+ // given
135
+ const root = makeTempRoot("lsp-message-global-");
136
+ process.env["PATH"] = join(root, "definitely-empty");
137
+ const result = runWithRequestContext(contextFor(root), () => findServerForExtension(".rs"));
138
+ if (result.status !== "not_installed") throw new Error("expected not_installed");
139
+
140
+ // when
141
+ const message = runWithRequestContext(contextFor(root), () => formatServerLookupError(result));
142
+
143
+ // then
144
+ expect(message).toContain("To install, run:");
145
+ expect(message).not.toContain("THIS repository");
146
+ expect(message).toContain("ACTION REQUIRED");
147
+ });
148
+
149
+ test("#given a pre-authorized install #when formatting the message #then both install routes stay visible", () => {
150
+ // given
151
+ const root = makeTempRoot("lsp-message-allowed-");
152
+ process.env["PATH"] = join(root, "definitely-empty");
153
+ const context = contextFor(root);
154
+ mkdirSync(join(root, "home-config"), { recursive: true });
155
+ writeFileSync(
156
+ context.installDecisionsPath,
157
+ `${JSON.stringify({ biome: { decision: "allowed", decidedAt: new Date().toISOString() } })}\n`,
158
+ );
159
+ const result = runWithRequestContext(context, () => findServerForExtension(".css"));
160
+ if (result.status !== "not_installed") throw new Error("expected not_installed");
161
+
162
+ // when
163
+ const message = runWithRequestContext(context, () => formatServerLookupError(result));
164
+
165
+ // then
166
+ expect(message).toContain("pre-authorized");
167
+ expect(message).toContain("bun add -d @biomejs/biome");
168
+ expect(message).toContain("npm install -g @biomejs/biome");
169
+ });
170
+ });
@@ -1,16 +1,28 @@
1
+ import { contextCwd } from "../request-context.js";
1
2
  import { getDisabledServerIds, getMergedServers } from "./config-loader.js";
2
3
  import { BUILTIN_SERVERS, LSP_INSTALL_HINTS } from "./server-definitions.js";
3
- import { isServerInstalled } from "./server-installation.js";
4
+ import { isServerInstalled, resolveServerBinary } from "./server-installation.js";
4
5
  import type { ServerLookupResult } from "./types.js";
5
6
 
7
+ /**
8
+ * Replaces the command name with the absolute binary path so the client spawns the exact
9
+ * binary that was resolved -- in particular a repo-local one that is absent from PATH.
10
+ */
11
+ function withResolvedCommand(command: string[], binaryPath: string): string[] {
12
+ return [binaryPath, ...command.slice(1)];
13
+ }
14
+
6
15
  export function findServerForExtension(ext: string): ServerLookupResult {
7
16
  const servers = getMergedServers();
17
+ const workingDirectory = contextCwd();
8
18
 
9
19
  for (const server of servers) {
10
- if (server.extensions.includes(ext) && isServerInstalled(server.command)) {
20
+ if (!server.extensions.includes(ext)) continue;
21
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
22
+ if (binaryPath !== null) {
11
23
  const resolvedServer = {
12
24
  id: server.id,
13
- command: server.command,
25
+ command: withResolvedCommand(server.command, binaryPath),
14
26
  extensions: server.extensions,
15
27
  priority: server.priority,
16
28
  };
@@ -70,6 +82,7 @@ export interface ServerStatus {
70
82
  export function getAllServers(): ServerStatus[] {
71
83
  const servers = getMergedServers();
72
84
  const disabled = getDisabledServerIds();
85
+ const workingDirectory = contextCwd();
73
86
 
74
87
  const result: ServerStatus[] = [];
75
88
  const seen = new Set<string>();
@@ -78,7 +91,7 @@ export function getAllServers(): ServerStatus[] {
78
91
  if (seen.has(server.id)) continue;
79
92
  result.push({
80
93
  id: server.id,
81
- installed: isServerInstalled(server.command),
94
+ installed: isServerInstalled(server.command, workingDirectory),
82
95
  extensions: server.extensions,
83
96
  disabled: false,
84
97
  source: server.source,
@@ -92,7 +105,7 @@ export function getAllServers(): ServerStatus[] {
92
105
  const builtin = BUILTIN_SERVERS[id];
93
106
  result.push({
94
107
  id,
95
- installed: builtin ? isServerInstalled(builtin.command) : false,
108
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
96
109
  extensions: builtin?.extensions ?? [],
97
110
  disabled: true,
98
111
  source: "disabled",
@@ -37,6 +37,7 @@ export class LspClientTransport {
37
37
  protected readonly initializeTimeoutMs: number;
38
38
  private workspaceApplyEditHandler: WorkspaceApplyEditHandler | null = null;
39
39
  private diagnosticPullSupported = false;
40
+ private documentFormattingSupported = false;
40
41
 
41
42
  constructor(
42
43
  protected readonly root: string,
@@ -71,6 +72,14 @@ export class LspClientTransport {
71
72
  return this.diagnosticPullSupported;
72
73
  }
73
74
 
75
+ protected setDocumentFormattingSupported(supported: boolean): void {
76
+ this.documentFormattingSupported = supported;
77
+ }
78
+
79
+ isDocumentFormattingSupported(): boolean {
80
+ return this.documentFormattingSupported;
81
+ }
82
+
74
83
  protected handlePublishDiagnostics(params: {
75
84
  readonly uri: string;
76
85
  readonly diagnostics: readonly Diagnostic[];
@@ -72,6 +72,14 @@ export interface Diagnostic {
72
72
  message: string;
73
73
  }
74
74
 
75
+ export interface FormattingOptions {
76
+ tabSize: number;
77
+ insertSpaces: boolean;
78
+ trimTrailingWhitespace?: boolean;
79
+ insertFinalNewline?: boolean;
80
+ trimFinalNewlines?: boolean;
81
+ }
82
+
75
83
  export interface TextDocumentIdentifier {
76
84
  uri: string;
77
85
  }
@@ -1,4 +1,4 @@
1
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1
+ import { mkdtempSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
@@ -87,6 +87,25 @@ describe("workspace edit adversarial inputs", () => {
87
87
  expect(readFileSync(outsideFile, "utf-8")).toBe("outside bytes\n");
88
88
  });
89
89
 
90
+ it("#given an in-workspace symlink to an outside file #when applying an edit #then rejects without modifying target", () => {
91
+ const workspace = makeTempDirectory("lsp-workspace-");
92
+ const outside = makeTempDirectory("lsp-outside-");
93
+ const outsideFile = join(outside, "outside.ts");
94
+ const canonicalWorkspace = realpathSync(workspace);
95
+ const linkedDirectory = join(canonicalWorkspace, "linked");
96
+ writeFileSync(outsideFile, "outside bytes\n", "utf-8");
97
+ symlinkSync(outside, linkedDirectory);
98
+
99
+ const result = applyWorkspaceEdit(
100
+ { changes: { [pathToFileURL(join(linkedDirectory, "outside.ts")).href]: [insertion()] } },
101
+ { workspaceRoot: canonicalWorkspace },
102
+ );
103
+
104
+ expect(result.success).toBe(false);
105
+ expect(result.errors.join("\n")).toContain("outside workspace");
106
+ expect(readFileSync(outsideFile, "utf-8")).toBe("outside bytes\n");
107
+ });
108
+
90
109
  it("#given annotations or mixed edit representations #when planned #then unsupported claims are rejected", () => {
91
110
  const workspace = makeTempDirectory("lsp-workspace-");
92
111
  const unsupported = [
@@ -0,0 +1,18 @@
1
+ /** Repository marker: an ancestor containing this always wins over intermediate package markers. */
2
+ export const GIT_WORKSPACE_MARKER = ".git" as const;
3
+
4
+ /**
5
+ * Package/project markers. On their own they resolve to the NEAREST marked directory, but inside a
6
+ * request cwd they are only a fallback: a `.git` ancestor further up collapses nested package roots
7
+ * (one client per repository instead of one per monorepo package).
8
+ */
9
+ export const PROJECT_WORKSPACE_MARKERS = [
10
+ "package.json",
11
+ "pyproject.toml",
12
+ "Cargo.toml",
13
+ "go.mod",
14
+ "pom.xml",
15
+ "build.gradle",
16
+ ] as const;
17
+
18
+ export const WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS] as const;
@@ -71,6 +71,9 @@ export async function runMcpStdioServer(
71
71
  await runJsonRpcStdioServer({
72
72
  input,
73
73
  output,
74
+ // Idle stays disabled: hosts of this CLI (legacy opencode configs and
75
+ // standalone lsp-tools-mcp users) have no evidenced respawn for an exited
76
+ // stdio server; opencode in particular marks it failed without retry.
74
77
  idleTimeoutMs: 0,
75
78
  parentWatchdog: options.parentWatchdog ?? {},
76
79
  handler: (request) => runWithRequestContext(requestContext, () => handleLspMcpRequest(request)),
@@ -168,4 +168,33 @@ describe("LspRequestContext", () => {
168
168
  capabilities: { installDecisionTool: true },
169
169
  });
170
170
  });
171
+
172
+ it("#given an injected LSP cwd #when standalone context is created #then it wins over process cwd without reading global env", () => {
173
+ const sessionRoot = tempRoot("lsp-context-session-");
174
+ const processRoot = tempRoot("lsp-context-process-");
175
+ const home = tempRoot("lsp-context-env-home-");
176
+
177
+ const context = createStandaloneMcpRequestContext({
178
+ env: {
179
+ LSP_TOOLS_MCP_CWD: sessionRoot,
180
+ },
181
+ homeDir: home,
182
+ });
183
+
184
+ expect(context.cwd).toBe(sessionRoot);
185
+ expect(context.projectConfigPaths).toEqual([join(sessionRoot, ".codex", "lsp-client.json")]);
186
+ expect(processRoot).not.toBe(context.cwd);
187
+ });
188
+
189
+ it("#given explicit cwd and an injected LSP cwd #when standalone context is created #then explicit cwd wins", () => {
190
+ const explicitRoot = tempRoot("lsp-context-explicit-");
191
+ const injectedRoot = tempRoot("lsp-context-injected-");
192
+
193
+ const context = createStandaloneMcpRequestContext({
194
+ cwd: explicitRoot,
195
+ env: { LSP_TOOLS_MCP_CWD: injectedRoot },
196
+ });
197
+
198
+ expect(context.cwd).toBe(explicitRoot);
199
+ });
171
200
  });
@@ -72,7 +72,7 @@ export function createStandaloneMcpRequestContext(
72
72
  input: StandaloneMcpRequestContextInput = {},
73
73
  ): LspRequestContext {
74
74
  const env = input.env ?? process.env;
75
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
75
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
76
76
  const home = input.homeDir ?? homedir();
77
77
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
78
78
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -104,6 +104,18 @@ const expectedToolSurface = [
104
104
  required: ["filePath", "line", "character", "newName"],
105
105
  },
106
106
  },
107
+ {
108
+ name: "format",
109
+ title: "LSP Format",
110
+ description: "Format a source file with its language server and write the returned edits to disk.",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ filePath: { type: "string", description: "Source file path to format." },
115
+ },
116
+ required: ["filePath"],
117
+ },
118
+ },
107
119
  {
108
120
  name: "install_decision",
109
121
  title: "LSP Install Decision",
@@ -128,7 +140,7 @@ const expectedToolSurface = [
128
140
  ];
129
141
 
130
142
  describe("LSP core tool surface", () => {
131
- test("#given tool descriptors #when listed #then the public eight-tool schemas are pinned", () => {
143
+ test("#given tool descriptors #when listed #then the public nine-tool schemas are pinned", () => {
132
144
  // given / when
133
145
  const surface = LSP_MCP_TOOLS.map((tool) => ({
134
146
  name: tool.name,
@@ -1,4 +1,5 @@
1
1
  import { executeLspDiagnostics } from "./diagnostics.js";
2
+ import { executeLspFormat } from "./format.js";
2
3
  import { executeLspInstallDecision } from "./install-decision.js";
3
4
  import { executeLspFindReferences, executeLspGotoDefinition } from "./navigation.js";
4
5
  import { executeLspPrepareRename, executeLspRename } from "./rename.js";
@@ -116,6 +117,19 @@ export const LSP_MCP_TOOLS: LspMcpTool[] = [
116
117
  ),
117
118
  execute: executeLspRename,
118
119
  },
120
+ {
121
+ name: "format",
122
+ aliases: ["lsp_format"],
123
+ title: "LSP Format",
124
+ description: "Format a source file with its language server and write the returned edits to disk.",
125
+ inputSchema: objectSchema(
126
+ {
127
+ filePath: { type: "string", description: "Source file path to format." },
128
+ },
129
+ ["filePath"],
130
+ ),
131
+ execute: executeLspFormat,
132
+ },
119
133
  {
120
134
  name: "install_decision",
121
135
  aliases: ["lsp_install_decision"],