oh-my-opencode 4.18.2 → 4.19.1

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 (307) hide show
  1. package/.agents/command/omomomo.md +1 -1
  2. package/.agents/skills/omomomo/SKILL.md +1 -1
  3. package/.opencode/command/omomomo.md +1 -1
  4. package/README.ja.md +6 -6
  5. package/README.ko.md +6 -6
  6. package/README.md +8 -8
  7. package/README.ru.md +6 -6
  8. package/README.zh-cn.md +6 -6
  9. package/dist/agents/atlas/agent.d.ts +7 -6
  10. package/dist/agents/gpt-prompt-identity.d.ts +3 -0
  11. package/dist/agents/sisyphus/gpt-5-5.d.ts +1 -1
  12. package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +1 -0
  13. package/dist/agents/sisyphus/index.d.ts +5 -0
  14. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  15. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  16. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  17. package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +2 -2
  18. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  19. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/index.js +781 -215
  22. package/dist/cli-node/index.js +781 -215
  23. package/dist/config/index.d.ts +1 -1
  24. package/dist/config/schema/agent-overrides.d.ts +48 -48
  25. package/dist/config/schema/browser-automation.d.ts +1 -0
  26. package/dist/config/schema/categories.d.ts +6 -6
  27. package/dist/config/schema/codegraph.d.ts +2 -0
  28. package/dist/config/schema/commands.d.ts +1 -3
  29. package/dist/config/schema/default-mode.d.ts +1 -1
  30. package/dist/config/schema/fallback-models.d.ts +5 -5
  31. package/dist/config/schema/goal.d.ts +7 -0
  32. package/dist/config/schema/hooks.d.ts +1 -1
  33. package/dist/config/schema/oh-my-opencode-config.d.ts +56 -58
  34. package/dist/config/schema/ralph-loop.d.ts +1 -1
  35. package/dist/config/schema.d.ts +1 -1
  36. package/dist/create-hooks.d.ts +1 -1
  37. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  38. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  39. package/dist/features/builtin-commands/types.d.ts +1 -1
  40. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  41. package/dist/hooks/codegraph-bootstrap/hook.d.ts +3 -2
  42. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  43. package/dist/hooks/goal/controller.d.ts +26 -0
  44. package/dist/hooks/goal/index.d.ts +23 -0
  45. package/dist/hooks/goal/prompt.d.ts +3 -0
  46. package/dist/hooks/goal/store.d.ts +8 -0
  47. package/dist/hooks/goal/tools.d.ts +10 -0
  48. package/dist/hooks/goal/types.d.ts +93 -0
  49. package/dist/hooks/goal/validation.d.ts +4 -0
  50. package/dist/hooks/index.d.ts +1 -0
  51. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  52. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  53. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  54. package/dist/hooks/start-work/notepad-scaffold.d.ts +10 -0
  55. package/dist/index.js +5398 -5109
  56. package/dist/oh-my-opencode.schema.json +34 -19
  57. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  58. package/dist/plugin/chat-message/types.d.ts +23 -10
  59. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  60. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  61. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  62. package/dist/plugin/stop-continuation.d.ts +2 -2
  63. package/dist/shared/omo-process-sweep.d.ts +18 -0
  64. package/dist/shared/system-directive.d.ts +0 -1
  65. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  66. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  67. package/dist/skills/ulw-plan/SKILL.md +31 -8
  68. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  69. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  70. package/dist/skills/ulw-research/SKILL.md +3 -3
  71. package/dist/testing/create-plugin-module.d.ts +1 -0
  72. package/dist/tools/delegate-task/types.d.ts +0 -1
  73. package/dist/tui.js +138 -80
  74. package/package.json +14 -14
  75. package/packages/git-bash-mcp/dist/cli.js +54 -8
  76. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +60 -0
  77. package/packages/lsp-core/src/lsp/client.ts +14 -1
  78. package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +2 -2
  79. package/packages/lsp-core/src/mcp.ts +9 -0
  80. package/packages/lsp-daemon/dist/cli.js +319 -51
  81. package/packages/lsp-daemon/dist/client.js +136 -48
  82. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
  83. package/packages/lsp-daemon/dist/daemon-client.js +4 -34
  84. package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
  85. package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
  86. package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
  87. package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
  88. package/packages/lsp-daemon/dist/daemon-server.js +5 -1
  89. package/packages/lsp-daemon/dist/index.js +137 -48
  90. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  91. package/packages/lsp-daemon/dist/proxy.js +1 -0
  92. package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
  93. package/packages/lsp-daemon/dist/version-reap.js +182 -0
  94. package/packages/lsp-tools-mcp/dist/cli.js +61 -10
  95. package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
  96. package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
  97. package/packages/lsp-tools-mcp/dist/tools.js +6 -1
  98. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  99. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
  100. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  101. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +22 -2
  103. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  104. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
  105. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
  106. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  107. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  108. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
  109. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
  110. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
  111. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
  112. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
  113. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
  114. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  115. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
  116. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
  117. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
  118. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
  119. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
  120. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
  121. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
  122. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
  123. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
  124. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
  125. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -0
  126. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  127. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  128. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  129. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  131. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  132. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  133. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
  135. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  136. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  137. package/packages/omo-codex/plugin/components/rules/dist/cli.js +11 -0
  138. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  139. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  140. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +11 -0
  141. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
  142. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  143. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  144. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  146. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  147. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  148. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  149. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  150. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  151. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  152. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  153. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  154. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  155. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  156. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  157. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
  158. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  159. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  160. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  161. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
  162. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  163. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  164. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  165. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  166. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
  168. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  169. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  170. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  171. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
  172. package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
  173. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
  174. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
  175. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
  176. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
  177. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  178. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  179. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +3 -3
  180. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
  181. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
  182. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
  191. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
  192. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
  193. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  194. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
  195. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
  196. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
  197. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
  202. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
  203. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -0
  204. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  206. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -6
  207. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
  208. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
  209. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
  211. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
  212. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
  213. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
  214. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
  216. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
  217. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
  218. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
  219. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
  220. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
  221. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
  222. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
  224. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
  225. package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
  226. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
  227. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
  228. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
  229. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
  230. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
  231. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
  232. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
  234. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
  235. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  236. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  237. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  238. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  239. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  240. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  241. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  242. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  243. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  244. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  245. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  246. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
  247. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  248. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -2
  249. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  250. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -2
  251. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  252. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  253. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  254. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  255. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  256. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  257. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  258. package/packages/omo-codex/plugin/package-lock.json +41 -41
  259. package/packages/omo-codex/plugin/package.json +1 -1
  260. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  261. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  262. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  263. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  264. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
  265. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  266. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
  267. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
  268. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  269. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  270. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
  271. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
  272. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
  273. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  274. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  275. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  276. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  277. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  278. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  279. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  280. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  281. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  282. package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
  283. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  284. package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +4 -1
  285. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  286. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  287. package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
  288. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  289. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  290. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  291. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  292. package/dist/skills/ultraresearch/SKILL.md +0 -10
  293. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  294. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  295. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  296. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  297. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  298. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  299. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  300. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  301. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  302. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  303. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  304. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  305. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  306. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  307. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -177,6 +177,81 @@ function isPlainRecord(value) {
177
177
  return typeof value === "object" && value !== null && !Array.isArray(value);
178
178
  }
179
179
 
180
+ // src/daemon-request-error.ts
181
+ class DaemonRequestError extends Error {
182
+ requestWritten;
183
+ constructor(message, requestWritten) {
184
+ super(message);
185
+ this.name = "DaemonRequestError";
186
+ this.requestWritten = requestWritten;
187
+ }
188
+ }
189
+
190
+ class DaemonAuthenticationRejectedError extends DaemonRequestError {
191
+ constructor() {
192
+ super("daemon authentication failed before dispatch", true);
193
+ this.name = "DaemonAuthenticationRejectedError";
194
+ }
195
+ }
196
+
197
+ class DaemonRequestCancelledError extends DaemonRequestError {
198
+ constructor(requestWritten) {
199
+ super("daemon request cancelled", requestWritten);
200
+ this.name = "DaemonRequestCancelledError";
201
+ }
202
+ }
203
+
204
+ class DaemonRequestTimedOutError extends DaemonRequestError {
205
+ timeoutMs;
206
+ constructor(requestWritten, timeoutMs) {
207
+ super("daemon request timed out", requestWritten);
208
+ this.name = "DaemonRequestTimedOutError";
209
+ this.timeoutMs = timeoutMs;
210
+ }
211
+ }
212
+
213
+ // src/daemon-failure-result.ts
214
+ function daemonFailureResult(paths, error) {
215
+ if (error instanceof DaemonRequestCancelledError)
216
+ return daemonCancelledResult(paths);
217
+ if (error instanceof DaemonRequestTimedOutError)
218
+ return daemonTimedOutResult(paths, error.timeoutMs);
219
+ return daemonUnreachableResult(paths, error);
220
+ }
221
+ function daemonCancelledResult(paths) {
222
+ const text = [
223
+ "LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
224
+ "The daemon stays available; no LSP work was applied. Retry when you are ready.",
225
+ `Socket: ${paths.socket}`
226
+ ].join(`
227
+ `);
228
+ return { content: [{ type: "text", text }], isError: true };
229
+ }
230
+ function daemonTimedOutResult(paths, timeoutMs) {
231
+ const text = [
232
+ `LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
233
+ "The daemon stays available but may be busy. Retry when you are ready.",
234
+ `Socket: ${paths.socket}`,
235
+ `Logs: ${paths.log}`
236
+ ].join(`
237
+ `);
238
+ return { content: [{ type: "text", text }], isError: true };
239
+ }
240
+ function daemonUnreachableResult(paths, error) {
241
+ const text = [
242
+ `LSP daemon unreachable: ${errorText(error)}.`,
243
+ "The MCP server is a thin proxy and never runs language servers in-process.",
244
+ `Socket: ${paths.socket}`,
245
+ `Logs: ${paths.log}`,
246
+ "The daemon is auto-started on demand and will be retried on the next request."
247
+ ].join(`
248
+ `);
249
+ return { content: [{ type: "text", text }], isError: true };
250
+ }
251
+ function errorText(error) {
252
+ return error instanceof Error ? error.message : String(error);
253
+ }
254
+
180
255
  // src/ensure-daemon.ts
181
256
  import { spawn } from "node:child_process";
182
257
  import { closeSync as closeSync2, mkdirSync as mkdirSync2, openSync as openSync2 } from "node:fs";
@@ -904,16 +979,35 @@ function bufferFromChunk(chunk) {
904
979
 
905
980
  // ../mcp-stdio-core/src/server.ts
906
981
  var DEFAULT_IDLE_TIMEOUT_MS = 10 * 60000;
982
+ var DEFAULT_PARENT_POLL_INTERVAL_MS = 30000;
907
983
  var noopLog = () => {};
984
+ function isProcessAlive(pid) {
985
+ try {
986
+ process.kill(pid, 0);
987
+ return true;
988
+ } catch (error) {
989
+ return !hasErrorCode(error, "ESRCH");
990
+ }
991
+ }
908
992
  async function runJsonRpcStdioServer(config) {
909
993
  const log = config.log ?? noopLog;
910
994
  const idleTimeoutMs = config.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
911
- const idleTimer = createIdleTimer(idleTimeoutMs, log, config.onIdleTimeout);
995
+ let isClosed = false;
996
+ const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
997
+ isClosed = true;
998
+ config.onIdleTimeout?.();
999
+ });
1000
+ const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
1001
+ isClosed = true;
1002
+ log("parent_exit", { parent_pid: parentPid, poll_interval_ms: pollIntervalMs });
1003
+ config.onParentExit?.();
1004
+ config.input.destroy();
1005
+ });
912
1006
  log("stdio_started", { cwd: process.cwd(), idle_timeout_ms: idleTimeoutMs });
913
1007
  idleTimer.arm();
914
1008
  try {
915
1009
  for await (const message of readStdioJsonRpcMessages(config.input)) {
916
- if (idleTimer.closed())
1010
+ if (isClosed)
917
1011
  break;
918
1012
  idleTimer.arm();
919
1013
  if (message.kind === "parse_error") {
@@ -924,8 +1018,12 @@ async function runJsonRpcStdioServer(config) {
924
1018
  if (!await handleRequest(message, config, log))
925
1019
  break;
926
1020
  }
1021
+ } catch (error) {
1022
+ if (!(isClosed && hasErrorCode(error, "ERR_STREAM_PREMATURE_CLOSE")))
1023
+ throw error;
927
1024
  } finally {
928
1025
  idleTimer.clear();
1026
+ watchdog.clear();
929
1027
  log("stdio_stopped");
930
1028
  }
931
1029
  }
@@ -981,9 +1079,33 @@ function isTerminalOutputError(error) {
981
1079
  return false;
982
1080
  return error.code === "EPIPE" || error.code === "ERR_STREAM_DESTROYED" || error.code === "ERR_STREAM_WRITE_AFTER_END";
983
1081
  }
984
- function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
1082
+ function hasErrorCode(error, code) {
1083
+ return error instanceof Error && "code" in error && error.code === code;
1084
+ }
1085
+ function createParentWatchdog(config, onDeadParent) {
1086
+ if (config === undefined)
1087
+ return { clear: () => {} };
1088
+ const pollIntervalMs = config.pollIntervalMs ?? DEFAULT_PARENT_POLL_INTERVAL_MS;
1089
+ if (pollIntervalMs <= 0)
1090
+ return { clear: () => {} };
1091
+ const parentPid = config.parentPid ?? process.ppid;
1092
+ const probeAlive = config.probeAlive ?? isProcessAlive;
1093
+ let fired = false;
1094
+ const timer = setInterval(() => {
1095
+ if (fired || probeAlive(parentPid))
1096
+ return;
1097
+ fired = true;
1098
+ onDeadParent(parentPid, pollIntervalMs);
1099
+ }, pollIntervalMs);
1100
+ timer.unref();
1101
+ return {
1102
+ clear: () => {
1103
+ clearInterval(timer);
1104
+ }
1105
+ };
1106
+ }
1107
+ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
985
1108
  let timer = null;
986
- let isClosed = false;
987
1109
  return {
988
1110
  arm: () => {
989
1111
  if (timer !== null)
@@ -991,9 +1113,8 @@ function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
991
1113
  if (idleTimeoutMs <= 0)
992
1114
  return;
993
1115
  timer = setTimeout(() => {
994
- isClosed = true;
995
1116
  log("idle_timeout", { idle_timeout_ms: idleTimeoutMs });
996
- onIdleTimeout?.();
1117
+ onTimeout();
997
1118
  }, idleTimeoutMs);
998
1119
  timer.unref();
999
1120
  },
@@ -1002,8 +1123,7 @@ function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
1002
1123
  return;
1003
1124
  clearTimeout(timer);
1004
1125
  timer = null;
1005
- },
1006
- closed: () => isClosed
1126
+ }
1007
1127
  };
1008
1128
  }
1009
1129
  // ../lsp-core/src/lsp/client-wrapper.ts
@@ -3625,8 +3745,13 @@ class LspClient extends LspClientConnection {
3625
3745
  if (!pushFallbackOnly)
3626
3746
  continue;
3627
3747
  const remainingMs = deadlineAt - Date.now();
3628
- if (remainingMs <= 0)
3748
+ if (remainingMs <= 0) {
3749
+ if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3750
+ const cached = this.documents.getPullCache(snapshot);
3751
+ return { items: cached === null ? [] : [...cached.diagnostics] };
3752
+ }
3629
3753
  return this.freshnessTimeout(absPath);
3754
+ }
3630
3755
  const waitMs = push.status === "wait" ? Math.min(push.waitMs, remainingMs) : remainingMs;
3631
3756
  await waitForDiagnosticsActivity(this.documents.waitForDiagnosticsActivity(snapshot, waitMs), signal);
3632
3757
  }
@@ -5715,29 +5840,6 @@ function parseContext(value) {
5715
5840
  // src/daemon-client.ts
5716
5841
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
5717
5842
  var nextProxyRequestId = 1;
5718
-
5719
- class DaemonRequestError extends Error {
5720
- requestWritten;
5721
- constructor(message, requestWritten) {
5722
- super(message);
5723
- this.name = "DaemonRequestError";
5724
- this.requestWritten = requestWritten;
5725
- }
5726
- }
5727
-
5728
- class DaemonAuthenticationRejectedError extends DaemonRequestError {
5729
- constructor() {
5730
- super("daemon authentication failed before dispatch", true);
5731
- this.name = "DaemonAuthenticationRejectedError";
5732
- }
5733
- }
5734
-
5735
- class DaemonRequestCancelledError extends DaemonRequestError {
5736
- constructor(requestWritten) {
5737
- super("daemon request cancelled", requestWritten);
5738
- this.name = "DaemonRequestCancelledError";
5739
- }
5740
- }
5741
5843
  async function callToolViaDaemon(name, args, options) {
5742
5844
  const context = requireContext(options.context);
5743
5845
  const paths = options.paths ?? daemonPaths();
@@ -5766,7 +5868,7 @@ async function callToolViaDaemon(name, args, options) {
5766
5868
  break;
5767
5869
  }
5768
5870
  }
5769
- return daemonUnreachableResult(paths, lastError);
5871
+ return daemonFailureResult(paths, lastError);
5770
5872
  }
5771
5873
  function callDiagnosticsViaDaemon(filePath, options) {
5772
5874
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
@@ -5811,17 +5913,6 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5811
5913
  Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5812
5914
  });
5813
5915
  }
5814
- function daemonUnreachableResult(paths, error) {
5815
- const text2 = [
5816
- `LSP daemon unreachable: ${errorText(error)}.`,
5817
- "The MCP server is a thin proxy and never runs language servers in-process.",
5818
- `Socket: ${paths.socket}`,
5819
- `Logs: ${paths.log}`,
5820
- "The daemon is auto-started on demand and will be retried on the next request."
5821
- ].join(`
5822
- `);
5823
- return { content: [{ type: "text", text: text2 }], isError: true };
5824
- }
5825
5916
  function sendToolCall(paths, token, name, args, options) {
5826
5917
  return new Promise((resolve9, reject) => {
5827
5918
  const socket = connect(paths.socket);
@@ -5861,7 +5952,7 @@ function sendToolCall(paths, token, name, args, options) {
5861
5952
  };
5862
5953
  const timer = setTimeout(() => {
5863
5954
  sendCancel();
5864
- finish(() => reject(new DaemonRequestError("daemon request timed out", requestWritten)));
5955
+ finish(() => reject(new DaemonRequestTimedOutError(requestWritten, options.timeoutMs)));
5865
5956
  }, options.timeoutMs);
5866
5957
  timer.unref();
5867
5958
  if (options.signal?.aborted) {
@@ -5920,9 +6011,6 @@ function allocateProxyRequestId() {
5920
6011
  function isRetryableTool(name) {
5921
6012
  return name !== "rename" && name !== "lsp_rename";
5922
6013
  }
5923
- function errorText(error) {
5924
- return error instanceof Error ? error.message : String(error);
5925
- }
5926
6014
 
5927
6015
  // src/client.ts
5928
6016
  import { statSync as statSync5 } from "node:fs";
@@ -1,16 +1,6 @@
1
1
  import { type LspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
2
2
  import type { ToolExecutionResult } from "@oh-my-opencode/lsp-core/tools";
3
3
  import { type DaemonPaths } from "./paths.js";
4
- export declare class DaemonRequestError extends Error {
5
- readonly requestWritten: boolean;
6
- constructor(message: string, requestWritten: boolean);
7
- }
8
- export declare class DaemonAuthenticationRejectedError extends DaemonRequestError {
9
- constructor();
10
- }
11
- export declare class DaemonRequestCancelledError extends DaemonRequestError {
12
- constructor(requestWritten: boolean);
13
- }
14
4
  export type DaemonToolContext = LspRequestContext;
15
5
  export interface CallToolOptions {
16
6
  context: DaemonToolContext;
@@ -3,6 +3,8 @@ import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { parseLspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
5
5
  import { isPlainRecord } from "@oh-my-opencode/mcp-stdio-core/record";
6
+ import { daemonFailureResult } from "./daemon-failure-result.js";
7
+ import { DaemonAuthenticationRejectedError, DaemonRequestCancelledError, DaemonRequestError, DaemonRequestTimedOutError, } from "./daemon-request-error.js";
6
8
  import { ensureDaemonRunning } from "./ensure-daemon.js";
7
9
  import { authEnvelope, isAuthErrorResponse, readAuthToken } from "./ipc-protocol.js";
8
10
  import { daemonPaths } from "./paths.js";
@@ -10,25 +12,6 @@ import { CONTEXT_KEY } from "./request-routing.js";
10
12
  import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
11
13
  const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
12
14
  let nextProxyRequestId = 1;
13
- export class DaemonRequestError extends Error {
14
- constructor(message, requestWritten) {
15
- super(message);
16
- this.name = "DaemonRequestError";
17
- this.requestWritten = requestWritten;
18
- }
19
- }
20
- export class DaemonAuthenticationRejectedError extends DaemonRequestError {
21
- constructor() {
22
- super("daemon authentication failed before dispatch", true);
23
- this.name = "DaemonAuthenticationRejectedError";
24
- }
25
- }
26
- export class DaemonRequestCancelledError extends DaemonRequestError {
27
- constructor(requestWritten) {
28
- super("daemon request cancelled", requestWritten);
29
- this.name = "DaemonRequestCancelledError";
30
- }
31
- }
32
15
  export async function callToolViaDaemon(name, args, options) {
33
16
  const context = requireContext(options.context);
34
17
  const paths = options.paths ?? daemonPaths();
@@ -59,7 +42,7 @@ export async function callToolViaDaemon(name, args, options) {
59
42
  break;
60
43
  }
61
44
  }
62
- return daemonUnreachableResult(paths, lastError);
45
+ return daemonFailureResult(paths, lastError);
63
46
  }
64
47
  export function callDiagnosticsViaDaemon(filePath, options) {
65
48
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
@@ -106,16 +89,6 @@ function ensureDaemonAvailable(paths, ensure, signal) {
106
89
  .then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
107
90
  });
108
91
  }
109
- function daemonUnreachableResult(paths, error) {
110
- const text = [
111
- `LSP daemon unreachable: ${errorText(error)}.`,
112
- "The MCP server is a thin proxy and never runs language servers in-process.",
113
- `Socket: ${paths.socket}`,
114
- `Logs: ${paths.log}`,
115
- "The daemon is auto-started on demand and will be retried on the next request.",
116
- ].join("\n");
117
- return { content: [{ type: "text", text }], isError: true };
118
- }
119
92
  function sendToolCall(paths, token, name, args, options) {
120
93
  return new Promise((resolve, reject) => {
121
94
  const socket = connect(paths.socket);
@@ -155,7 +128,7 @@ function sendToolCall(paths, token, name, args, options) {
155
128
  };
156
129
  const timer = setTimeout(() => {
157
130
  sendCancel();
158
- finish(() => reject(new DaemonRequestError("daemon request timed out", requestWritten)));
131
+ finish(() => reject(new DaemonRequestTimedOutError(requestWritten, options.timeoutMs)));
159
132
  }, options.timeoutMs);
160
133
  timer.unref();
161
134
  if (options.signal?.aborted) {
@@ -214,6 +187,3 @@ function allocateProxyRequestId() {
214
187
  function isRetryableTool(name) {
215
188
  return name !== "rename" && name !== "lsp_rename";
216
189
  }
217
- function errorText(error) {
218
- return error instanceof Error ? error.message : String(error);
219
- }
@@ -0,0 +1,3 @@
1
+ import type { ToolExecutionResult } from "@oh-my-opencode/lsp-core/tools";
2
+ import type { DaemonPaths } from "./paths.js";
3
+ export declare function daemonFailureResult(paths: DaemonPaths, error: unknown): ToolExecutionResult;
@@ -0,0 +1,38 @@
1
+ import { DaemonRequestCancelledError, DaemonRequestTimedOutError } from "./daemon-request-error.js";
2
+ export function daemonFailureResult(paths, error) {
3
+ if (error instanceof DaemonRequestCancelledError)
4
+ return daemonCancelledResult(paths);
5
+ if (error instanceof DaemonRequestTimedOutError)
6
+ return daemonTimedOutResult(paths, error.timeoutMs);
7
+ return daemonUnreachableResult(paths, error);
8
+ }
9
+ function daemonCancelledResult(paths) {
10
+ const text = [
11
+ "LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
12
+ "The daemon stays available; no LSP work was applied. Retry when you are ready.",
13
+ `Socket: ${paths.socket}`,
14
+ ].join("\n");
15
+ return { content: [{ type: "text", text }], isError: true };
16
+ }
17
+ function daemonTimedOutResult(paths, timeoutMs) {
18
+ const text = [
19
+ `LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
20
+ "The daemon stays available but may be busy. Retry when you are ready.",
21
+ `Socket: ${paths.socket}`,
22
+ `Logs: ${paths.log}`,
23
+ ].join("\n");
24
+ return { content: [{ type: "text", text }], isError: true };
25
+ }
26
+ function daemonUnreachableResult(paths, error) {
27
+ const text = [
28
+ `LSP daemon unreachable: ${errorText(error)}.`,
29
+ "The MCP server is a thin proxy and never runs language servers in-process.",
30
+ `Socket: ${paths.socket}`,
31
+ `Logs: ${paths.log}`,
32
+ "The daemon is auto-started on demand and will be retried on the next request.",
33
+ ].join("\n");
34
+ return { content: [{ type: "text", text }], isError: true };
35
+ }
36
+ function errorText(error) {
37
+ return error instanceof Error ? error.message : String(error);
38
+ }
@@ -0,0 +1,14 @@
1
+ export declare class DaemonRequestError extends Error {
2
+ readonly requestWritten: boolean;
3
+ constructor(message: string, requestWritten: boolean);
4
+ }
5
+ export declare class DaemonAuthenticationRejectedError extends DaemonRequestError {
6
+ constructor();
7
+ }
8
+ export declare class DaemonRequestCancelledError extends DaemonRequestError {
9
+ constructor(requestWritten: boolean);
10
+ }
11
+ export declare class DaemonRequestTimedOutError extends DaemonRequestError {
12
+ readonly timeoutMs: number;
13
+ constructor(requestWritten: boolean, timeoutMs: number);
14
+ }
@@ -0,0 +1,26 @@
1
+ export class DaemonRequestError extends Error {
2
+ constructor(message, requestWritten) {
3
+ super(message);
4
+ this.name = "DaemonRequestError";
5
+ this.requestWritten = requestWritten;
6
+ }
7
+ }
8
+ export class DaemonAuthenticationRejectedError extends DaemonRequestError {
9
+ constructor() {
10
+ super("daemon authentication failed before dispatch", true);
11
+ this.name = "DaemonAuthenticationRejectedError";
12
+ }
13
+ }
14
+ export class DaemonRequestCancelledError extends DaemonRequestError {
15
+ constructor(requestWritten) {
16
+ super("daemon request cancelled", requestWritten);
17
+ this.name = "DaemonRequestCancelledError";
18
+ }
19
+ }
20
+ export class DaemonRequestTimedOutError extends DaemonRequestError {
21
+ constructor(requestWritten, timeoutMs) {
22
+ super("daemon request timed out", requestWritten);
23
+ this.name = "DaemonRequestTimedOutError";
24
+ this.timeoutMs = timeoutMs;
25
+ }
26
+ }
@@ -1,11 +1,12 @@
1
1
  import { chmodSync } from "node:fs";
2
2
  import { createServer } from "node:net";
3
3
  import { disposeDefaultLspManager, getLspManager } from "@oh-my-opencode/lsp-core/lsp/manager";
4
- import { setPrivateFileMode } from "./ipc-protocol.js";
5
4
  import { pingDaemon } from "./ensure-daemon.js";
5
+ import { setPrivateFileMode } from "./ipc-protocol.js";
6
6
  import { acquireStartupLease, DaemonStartupDeferredError, endpointIdentity, removeDaemonMetadataForOwner, writeDaemonOwner, } from "./ownership.js";
7
7
  import { handleDaemonMessage } from "./request-routing.js";
8
8
  import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
9
+ import { reapStaleDaemonVersions } from "./version-reap.js";
9
10
  export { DaemonAlreadyRunningError, DaemonStartupDeferredError } from "./ownership.js";
10
11
  const DEFAULT_IDLE_SHUTDOWN_MS = 30 * 60_000;
11
12
  const DEFAULT_IDLE_CHECK_INTERVAL_MS = 60_000;
@@ -53,6 +54,9 @@ export async function startDaemonServer(paths, options = {}) {
53
54
  throw error;
54
55
  }
55
56
  lease.lock.release();
57
+ // Best-effort cross-version reap: the daemon now owns its version, so older
58
+ // sibling versions may be reaped. Never block or crash startup on failure.
59
+ void reapStaleDaemonVersions(paths).catch((error) => logServerError(error));
56
60
  let closed = false;
57
61
  const close = async () => {
58
62
  if (closed)