oh-my-opencode 4.19.4 → 5.0.0-beta.2

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 (268) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +6 -5
  4. package/README.ru.md +1 -1
  5. package/README.zh-cn.md +1 -1
  6. package/bin/oh-my-opencode.js +14 -1
  7. package/bin/oh-my-opencode.test.ts +21 -0
  8. package/dist/cli/index.js +1452 -703
  9. package/dist/cli-node/index.js +1452 -703
  10. package/dist/config/schema/agent-overrides.d.ts +528 -0
  11. package/dist/config/schema/oh-my-opencode-config.d.ts +495 -0
  12. package/dist/features/monitor/batcher.d.ts +3 -1
  13. package/dist/features/monitor/manager-internals.d.ts +1 -0
  14. package/dist/features/monitor/output-injector-types.d.ts +2 -0
  15. package/dist/features/monitor/output-injector.d.ts +6 -0
  16. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  17. package/dist/hooks/todo-continuation-enforcer/unrecoverable-request-error.d.ts +9 -0
  18. package/dist/hooks/tool-pair-validator/hook.test-support.d.ts +29 -0
  19. package/dist/hooks/tool-pair-validator/tool-part-ids.d.ts +14 -5
  20. package/dist/hooks/tool-pair-validator/tool-result-repair.d.ts +4 -3
  21. package/dist/hooks/tool-pair-validator/types.d.ts +5 -22
  22. package/dist/index.js +2776 -2240
  23. package/dist/mcp/lsp.d.ts +1 -0
  24. package/dist/oh-my-opencode.schema.json +1466 -131
  25. package/dist/shared/tmux/constants.d.ts +1 -1
  26. package/dist/skills/ast-grep/SOURCE +1 -1
  27. package/dist/skills/ast-grep/install.ps1 +2 -2
  28. package/dist/skills/ast-grep/install.sh +1 -1
  29. package/dist/skills/ast-grep/references/install.md +2 -2
  30. package/dist/skills/ast-grep/tests/smoke.sh +1 -1
  31. package/dist/skills/start-work/SKILL.md +54 -9
  32. package/dist/skills/ultimate-browsing/SKILL.md +2 -2
  33. package/dist/skills/ultimate-browsing/engine/__main__.py +8 -1
  34. package/dist/skills/ultimate-browsing/engine/bias_check.py +11 -0
  35. package/dist/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
  36. package/dist/skills/ultimate-browsing/engine/result_schema.py +10 -1
  37. package/dist/skills/ultimate-browsing/engine/surrogate.py +214 -0
  38. package/dist/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
  39. package/dist/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
  40. package/dist/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
  41. package/dist/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
  42. package/dist/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
  43. package/dist/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
  44. package/dist/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
  45. package/dist/skills/ultimate-browsing/engine/validators.py +46 -0
  46. package/dist/skills/ultimate-browsing/engine/waf_detector.py +1 -1
  47. package/dist/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
  48. package/dist/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  49. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  50. package/dist/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  51. package/dist/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
  52. package/dist/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
  53. package/dist/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
  54. package/dist/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
  55. package/dist/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
  56. package/dist/skills/ulw-plan/SKILL.md +1 -1
  57. package/dist/skills/ulw-plan/references/full-workflow.md +3 -3
  58. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  59. package/dist/skills/ulw-research/SKILL.md +15 -10
  60. package/dist/tui.js +307 -28
  61. package/docs/reference/web-terminal-visual-qa.md +1 -1
  62. package/package.json +27 -19
  63. package/packages/lsp-core/src/lsp/connection.ts +1 -1
  64. package/packages/lsp-daemon/dist/cli.js +27 -13
  65. package/packages/lsp-daemon/dist/client.js +49 -35
  66. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
  67. package/packages/lsp-daemon/dist/ensure-daemon.js +18 -5
  68. package/packages/lsp-daemon/dist/index.js +34 -20
  69. package/packages/lsp-tools-mcp/dist/cli.js +1 -1
  70. package/packages/lsp-tools-mcp/dist/lsp/manager.js +1 -1
  71. package/packages/lsp-tools-mcp/dist/mcp.js +1 -1
  72. package/packages/lsp-tools-mcp/dist/tools.js +1 -1
  73. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  74. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +268 -92
  75. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  76. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  77. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -7
  78. package/packages/omo-codex/plugin/components/bootstrap/src/worker.ts +3 -0
  79. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +106 -6
  80. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +106 -6
  81. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  82. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  83. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  84. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  85. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  87. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  88. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  89. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +56 -42
  90. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  91. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  92. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  93. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  94. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +1 -0
  95. package/packages/omo-codex/plugin/components/start-work-continuation/README.md +5 -1
  96. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +2 -1
  97. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +18 -0
  98. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  99. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  100. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +21 -0
  101. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +105 -0
  102. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  103. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  104. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  105. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  106. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
  107. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  108. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  109. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  110. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  111. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  112. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  113. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  114. package/packages/omo-codex/plugin/components/ultrawork/directive.md +3 -2
  115. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  116. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  117. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +3 -2
  118. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +1 -1
  119. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +3 -3
  120. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  121. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  122. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +2 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -11
  124. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +3 -2
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +1 -1
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +9 -9
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +1 -1
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +66 -66
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +4 -4
  131. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +1 -1
  132. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -1
  133. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +1 -1
  134. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +1 -1
  135. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +2 -2
  136. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  137. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  138. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -3
  139. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -25
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +1 -1
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +9 -9
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +1 -1
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +1 -1
  144. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +4 -4
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +1 -1
  146. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -1
  147. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +1 -1
  148. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +1 -1
  149. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +2 -2
  150. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -2
  151. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +1 -1
  152. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-helpers.test.ts +2 -2
  153. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +1 -1
  154. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +2 -2
  155. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +1 -1
  156. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -5
  157. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +1 -1
  158. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +1 -1
  159. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +1 -1
  160. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  161. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  165. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  170. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  171. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  172. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  173. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  174. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  175. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  176. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  177. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  179. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  181. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  184. package/packages/omo-codex/plugin/package-lock.json +13 -13
  185. package/packages/omo-codex/plugin/package.json +1 -1
  186. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +4 -4
  187. package/packages/omo-codex/plugin/skills/ast-grep/SOURCE +1 -1
  188. package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +2 -2
  189. package/packages/omo-codex/plugin/skills/ast-grep/install.sh +1 -1
  190. package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
  191. package/packages/omo-codex/plugin/skills/ast-grep/tests/smoke.sh +1 -1
  192. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +54 -9
  193. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -2
  194. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +8 -1
  195. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +11 -0
  196. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
  197. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +10 -1
  198. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogate.py +214 -0
  199. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
  200. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
  201. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
  202. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
  203. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
  204. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
  205. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
  206. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +46 -0
  207. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +1 -1
  208. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
  209. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  210. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  211. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  212. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
  213. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
  214. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
  215. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
  216. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
  217. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +3 -2
  218. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -3
  219. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -25
  220. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +1 -1
  221. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +3 -3
  222. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  223. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +15 -10
  224. package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +12 -12
  225. package/packages/omo-codex/plugin/test/bootstrap-orchestration.test.mjs +36 -4
  226. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +1 -1
  227. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +4 -4
  228. package/packages/omo-codex/scripts/install-bin-links.test.mjs +56 -2
  229. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +6 -6
  230. package/packages/omo-codex/scripts/install-dist/install-local.mjs +115 -61
  231. package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +4 -4
  232. package/packages/omo-codex/scripts/install-local.test.mjs +5 -2
  233. package/packages/shared-skills/index.mjs +19 -1
  234. package/packages/shared-skills/skills/ast-grep/SOURCE +1 -1
  235. package/packages/shared-skills/skills/ast-grep/install.ps1 +2 -2
  236. package/packages/shared-skills/skills/ast-grep/install.sh +1 -1
  237. package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
  238. package/packages/shared-skills/skills/ast-grep/tests/smoke.sh +1 -1
  239. package/packages/shared-skills/skills/start-work/SKILL.md +54 -9
  240. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -2
  241. package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +8 -1
  242. package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +11 -0
  243. package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
  244. package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +10 -1
  245. package/packages/shared-skills/skills/ultimate-browsing/engine/surrogate.py +214 -0
  246. package/packages/shared-skills/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
  247. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
  248. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
  249. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
  250. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
  251. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
  252. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
  253. package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +46 -0
  254. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +1 -1
  255. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
  256. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  257. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  258. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  259. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
  260. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
  261. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
  262. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
  263. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
  264. package/packages/shared-skills/skills/ulw-plan/SKILL.md +1 -1
  265. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +3 -3
  266. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  267. package/packages/shared-skills/skills/ulw-research/SKILL.md +15 -10
  268. package/postinstall.mjs +6 -0
package/dist/cli/index.js CHANGED
@@ -2145,7 +2145,7 @@ var package_default;
2145
2145
  var init_package = __esm(() => {
2146
2146
  package_default = {
2147
2147
  name: "oh-my-opencode",
2148
- version: "4.19.4",
2148
+ version: "5.0.0-beta.2",
2149
2149
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2150
2150
  main: "./dist/index.js",
2151
2151
  types: "dist/index.d.ts",
@@ -2153,6 +2153,7 @@ var init_package = __esm(() => {
2153
2153
  workspaces: [
2154
2154
  "packages/rules-engine",
2155
2155
  "packages/delegate-core",
2156
+ "packages/ast-grep-mcp",
2156
2157
  "packages/git-bash-mcp",
2157
2158
  "packages/mcp-stdio-core",
2158
2159
  "packages/mcp-client-core",
@@ -2167,6 +2168,7 @@ var init_package = __esm(() => {
2167
2168
  "packages/team-core",
2168
2169
  "packages/openclaw-core",
2169
2170
  "packages/boulder-state",
2171
+ "packages/memory-core",
2170
2172
  "packages/telemetry-core",
2171
2173
  "packages/claude-code-compat-core",
2172
2174
  "packages/skills-loader-core",
@@ -2177,12 +2179,13 @@ var init_package = __esm(() => {
2177
2179
  "packages/senpi-task",
2178
2180
  "packages/pi-goal",
2179
2181
  "packages/pi-webfetch",
2180
- "packages/omo-opencode"
2182
+ "packages/omo-opencode",
2183
+ "packages/omo-native"
2181
2184
  ],
2182
2185
  bin: {
2183
2186
  "oh-my-opencode": "bin/oh-my-opencode.js",
2184
2187
  "oh-my-openagent": "bin/oh-my-opencode.js",
2185
- omo: "bin/oh-my-opencode.js",
2188
+ "omo-agent-toolkit": "bin/oh-my-opencode.js",
2186
2189
  lazycodex: "bin/oh-my-opencode.js",
2187
2190
  "lazycodex-ai": "bin/oh-my-opencode.js"
2188
2191
  },
@@ -2254,8 +2257,8 @@ var init_package = __esm(() => {
2254
2257
  "build:codex-install": "bun run script/build-codex-install.ts",
2255
2258
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
2256
2259
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
2257
- "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:senpi-plugin:stage",
2258
- "build:senpi-plugin:stage": "bun run build:materialize-frontend && node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
2260
+ "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:ast-grep-mcp && bun run build:senpi-plugin:stage",
2261
+ "build:senpi-plugin:stage": "bun run build:materialize-frontend && node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-ast-grep-mcp-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-agent-toolkit.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
2259
2262
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
2260
2263
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
2261
2264
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
@@ -2264,6 +2267,7 @@ var init_package = __esm(() => {
2264
2267
  "build:all": "bun run build && bun run build:binaries",
2265
2268
  "build:binaries": "bun run script/build-binaries.ts",
2266
2269
  "build:schema": "bun run script/build-schema.ts",
2270
+ "build:omo-native": "bun run script/build-omo-native.ts",
2267
2271
  "build:omo-schema": "bun run script/build-omo-schema.ts",
2268
2272
  "build:model-capabilities": "bun run script/build-model-capabilities.ts",
2269
2273
  clean: "rm -rf dist",
@@ -2273,13 +2277,14 @@ var init_package = __esm(() => {
2273
2277
  prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
2274
2278
  "test:model-capabilities": "bun test packages/model-core/src/model-capability-aliases.test.ts packages/model-core/src/model-capability-guardrails.test.ts packages/model-core/src/model-capabilities.test.ts packages/omo-opencode/src/cli/doctor/checks/model-resolution.test.ts --bail",
2275
2279
  typecheck: "tsgo --noEmit && bun run typecheck:script && bun run typecheck:packages",
2276
- "typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/delegate-core/tsconfig.json && tsgo --noEmit -p packages/mcp-stdio-core/tsconfig.json && tsgo --noEmit -p packages/mcp-client-core/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/lsp-core/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/omo-config-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/tmux-core/tsconfig.json && tsgo --noEmit -p packages/team-core/tsconfig.json && tsgo --noEmit -p packages/openclaw-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/telemetry-core/tsconfig.json && tsgo --noEmit -p packages/claude-code-compat-core/tsconfig.json && tsgo --noEmit -p packages/skills-loader-core/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/plugin/shared/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && tsgo --noEmit -p packages/senpi-task/tsconfig.json && tsgo --noEmit -p packages/pi-goal/tsconfig.json && tsgo --noEmit -p packages/pi-webfetch/tsconfig.json && tsgo --noEmit -p packages/omo-opencode/tsconfig.json",
2280
+ "typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/delegate-core/tsconfig.json && tsgo --noEmit -p packages/mcp-stdio-core/tsconfig.json && tsgo --noEmit -p packages/mcp-client-core/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/lsp-core/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/omo-config-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/tmux-core/tsconfig.json && tsgo --noEmit -p packages/team-core/tsconfig.json && tsgo --noEmit -p packages/openclaw-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/memory-core/tsconfig.json && tsgo --noEmit -p packages/telemetry-core/tsconfig.json && tsgo --noEmit -p packages/claude-code-compat-core/tsconfig.json && tsgo --noEmit -p packages/skills-loader-core/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/plugin/shared/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && tsgo --noEmit -p packages/senpi-task/tsconfig.json && tsgo --noEmit -p packages/pi-goal/tsconfig.json && tsgo --noEmit -p packages/pi-webfetch/tsconfig.json && tsgo --noEmit -p packages/omo-opencode/tsconfig.json && tsgo --noEmit -p packages/omo-native/tsconfig.json",
2277
2281
  "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
2278
2282
  test: "bun test",
2279
2283
  "test:codex": "bun run build:codex-install && bun run build:git-bash-mcp && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && npm --prefix packages/lsp-tools-mcp test && npm --prefix packages/omo-codex/plugin ci && npm --prefix packages/omo-codex/plugin/components/ulw-loop test && bun run --cwd packages/omo-codex/plugin build && npm --prefix packages/omo-codex/plugin/components/codegraph run typecheck && npm --prefix packages/omo-codex/plugin/components/codegraph test && node scripts/check-third-party-notices.mjs --ship && bun test packages/omo-opencode/src/cli/cli-installer.platform.test.ts packages/omo-codex/src/install/codex-cache.test.ts packages/omo-codex/src/install/codex-cleanup.test.ts packages/omo-codex/src/install/codex-config-agent-cleanup.test.ts packages/omo-codex/src/install/codex-config-autonomous-features.test.ts packages/omo-codex/src/install/codex-config-reasoning.test.ts packages/omo-codex/src/install/codex-config-toml.test.ts packages/omo-codex/src/install/codex-project-local-cleanup.test.ts packages/omo-codex/src/install/install-codex-project-local-cleanup.test.ts packages/omo-codex/src/install/install-codex.test.ts packages/omo-codex/src/install/install-codex-packaged.test.ts packages/omo-codex/src/install/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-cli-args.test.mjs packages/omo-codex/scripts/install-delegated-command.test.mjs packages/omo-codex/scripts/install-config-autonomous-features.test.mjs packages/omo-codex/scripts/install-config-autonomous.test.mjs packages/omo-codex/scripts/install-config-reasoning.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-hook-targets.test.mjs packages/omo-codex/scripts/install-project-local-cleanup.test.mjs packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs packages/omo-codex/scripts/install-local-entrypoint.test.mjs packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-marketplace-cache.test.mjs packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-packaged-local.test.mjs packages/omo-codex/scripts/install-generated-bundle.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs",
2280
2284
  "test:senpi": "bun run build:senpi-plugin && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && bun test packages/omo-senpi",
2281
2285
  "test:windows-codex": "bun run test:codex",
2282
- "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
2286
+ "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build",
2287
+ "build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build"
2283
2288
  },
2284
2289
  keywords: [
2285
2290
  "opencode",
@@ -2320,7 +2325,9 @@ var init_package = __esm(() => {
2320
2325
  zod: "^4.4.3"
2321
2326
  },
2322
2327
  devDependencies: {
2328
+ "@code-yeongyu/senpi": "2026.8.9-2",
2323
2329
  "@oh-my-opencode/agents-md-core": "workspace:*",
2330
+ "@oh-my-opencode/ast-grep-mcp": "workspace:*",
2324
2331
  "@oh-my-opencode/boulder-state": "workspace:*",
2325
2332
  "@oh-my-opencode/claude-code-compat-core": "workspace:*",
2326
2333
  "@oh-my-opencode/comment-checker-core": "workspace:*",
@@ -2328,6 +2335,7 @@ var init_package = __esm(() => {
2328
2335
  "@oh-my-opencode/git-bash-mcp": "workspace:*",
2329
2336
  "@oh-my-opencode/hashline-core": "workspace:*",
2330
2337
  "@oh-my-opencode/lsp-core": "workspace:*",
2338
+ "@oh-my-opencode/memory-core": "workspace:*",
2331
2339
  "@oh-my-opencode/mcp-client-core": "workspace:*",
2332
2340
  "@oh-my-opencode/mcp-stdio-core": "workspace:*",
2333
2341
  "@oh-my-opencode/model-core": "workspace:*",
@@ -2357,18 +2365,18 @@ var init_package = __esm(() => {
2357
2365
  typescript: "^7.0.2"
2358
2366
  },
2359
2367
  optionalDependencies: {
2360
- "oh-my-opencode-darwin-arm64": "4.19.4",
2361
- "oh-my-opencode-darwin-x64": "4.19.4",
2362
- "oh-my-opencode-darwin-x64-baseline": "4.19.4",
2363
- "oh-my-opencode-linux-arm64": "4.19.4",
2364
- "oh-my-opencode-linux-arm64-musl": "4.19.4",
2365
- "oh-my-opencode-linux-x64": "4.19.4",
2366
- "oh-my-opencode-linux-x64-baseline": "4.19.4",
2367
- "oh-my-opencode-linux-x64-musl": "4.19.4",
2368
- "oh-my-opencode-linux-x64-musl-baseline": "4.19.4",
2369
- "oh-my-opencode-windows-arm64": "4.19.4",
2370
- "oh-my-opencode-windows-x64": "4.19.4",
2371
- "oh-my-opencode-windows-x64-baseline": "4.19.4"
2368
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.2",
2369
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.2",
2370
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.2",
2371
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.2",
2372
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.2",
2373
+ "oh-my-opencode-linux-x64": "5.0.0-beta.2",
2374
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.2",
2375
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.2",
2376
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.2",
2377
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.2",
2378
+ "oh-my-opencode-windows-x64": "5.0.0-beta.2",
2379
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.2"
2372
2380
  },
2373
2381
  overrides: {
2374
2382
  "@earendil-works/pi-agent-core": "0.80.3",
@@ -22395,6 +22403,80 @@ var init_codegraph = __esm(() => {
22395
22403
  }).strict();
22396
22404
  });
22397
22405
 
22406
+ // packages/omo-config-core/src/schema/memory.ts
22407
+ var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
22408
+ var init_memory = __esm(() => {
22409
+ init_zod();
22410
+ OmoMemoryReflectionTriggerSchema = object({
22411
+ step_count: number2().int().nonnegative().default(0),
22412
+ on_compaction: boolean2().default(true)
22413
+ }).strict();
22414
+ OmoMemoryReflectionSchema = object({
22415
+ trigger: OmoMemoryReflectionTriggerSchema.default({ step_count: 0, on_compaction: true }),
22416
+ merge: _enum2(["auto", "integration"]).default("auto"),
22417
+ category: string2().min(1).default("quick"),
22418
+ timeout_minutes: number2().int().positive().default(15),
22419
+ sandbox: _enum2(["auto", "required", "off"]).default("auto")
22420
+ }).strict();
22421
+ OmoMemorySyncSchema = object({
22422
+ remote: string2().min(1).optional(),
22423
+ enabled: boolean2().default(true)
22424
+ }).strict();
22425
+ OmoMemorySearchSchema = object({
22426
+ enabled: boolean2().default(true)
22427
+ }).strict();
22428
+ OmoMemoryReflectionTriggerLayerSchema = object({
22429
+ step_count: number2().int().nonnegative().optional(),
22430
+ on_compaction: boolean2().optional()
22431
+ }).strict();
22432
+ OmoMemoryReflectionLayerSchema = object({
22433
+ trigger: OmoMemoryReflectionTriggerLayerSchema.optional(),
22434
+ merge: _enum2(["auto", "integration"]).optional(),
22435
+ category: string2().min(1).optional(),
22436
+ timeout_minutes: number2().int().positive().optional(),
22437
+ sandbox: _enum2(["auto", "required", "off"]).optional()
22438
+ }).strict();
22439
+ OmoMemorySyncLayerSchema = object({
22440
+ remote: string2().min(1).optional(),
22441
+ enabled: boolean2().optional()
22442
+ }).strict();
22443
+ OmoMemorySearchLayerSchema = object({
22444
+ enabled: boolean2().optional()
22445
+ }).strict();
22446
+ OmoMemoryAgentOverridesSchema = object({
22447
+ enabled: boolean2().optional(),
22448
+ agent: string2().min(1).optional(),
22449
+ reflection: OmoMemoryReflectionLayerSchema.optional(),
22450
+ sync: OmoMemorySyncLayerSchema.optional(),
22451
+ search: OmoMemorySearchLayerSchema.optional(),
22452
+ compile_warn_tokens: number2().int().positive().optional()
22453
+ }).strict();
22454
+ OmoMemorySettingsSchema = object({
22455
+ enabled: boolean2().default(true),
22456
+ agent: string2().min(1).default("auto"),
22457
+ reflection: OmoMemoryReflectionSchema.default({
22458
+ trigger: { step_count: 0, on_compaction: true },
22459
+ merge: "auto",
22460
+ category: "quick",
22461
+ timeout_minutes: 15,
22462
+ sandbox: "auto"
22463
+ }),
22464
+ sync: OmoMemorySyncSchema.default({ enabled: true }),
22465
+ search: OmoMemorySearchSchema.default({ enabled: true }),
22466
+ compile_warn_tokens: number2().int().positive().default(30000),
22467
+ agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
22468
+ }).strict();
22469
+ OmoMemorySettingsLayerSchema = object({
22470
+ enabled: boolean2().optional(),
22471
+ agent: string2().min(1).optional(),
22472
+ reflection: OmoMemoryReflectionLayerSchema.optional(),
22473
+ sync: OmoMemorySyncLayerSchema.optional(),
22474
+ search: OmoMemorySearchLayerSchema.optional(),
22475
+ compile_warn_tokens: number2().int().positive().optional(),
22476
+ agents: record(string2(), OmoMemoryAgentOverridesSchema).optional()
22477
+ }).strict();
22478
+ });
22479
+
22398
22480
  // packages/omo-config-core/src/schema/model-catalog.ts
22399
22481
  function isRecord5(value) {
22400
22482
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -22418,9 +22500,18 @@ var init_model_catalog = __esm(() => {
22418
22500
  });
22419
22501
 
22420
22502
  // packages/omo-config-core/src/schema/task.ts
22421
- var OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskSettingsSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
22503
+ import { availableParallelism } from "os";
22504
+ function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism) {
22505
+ const record2 = record(string2(), unknown()).parse(input);
22506
+ return OmoTaskSettingsSchema.parse({
22507
+ ...record2,
22508
+ residency_max_children: record2["residency_max_children"] ?? Math.max(8, resolveParallelism() * 3)
22509
+ });
22510
+ }
22511
+ var ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskSettingsSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
22422
22512
  var init_task = __esm(() => {
22423
22513
  init_zod();
22514
+ ResidencyMaxChildrenInputSchema = union([number2().int().positive(), literal("unlimited")]);
22424
22515
  OmoTaskWaitSchema = object({
22425
22516
  min_ms: number2().int().positive().default(5000),
22426
22517
  default_ms: number2().int().positive().default(60000),
@@ -22440,10 +22531,11 @@ var init_task = __esm(() => {
22440
22531
  provider_concurrency: record(string2(), number2().int().positive()).optional(),
22441
22532
  model_concurrency: record(string2(), number2().int().positive()).optional(),
22442
22533
  max_depth: number2().int().nonnegative().default(1),
22443
- residency_max_children: number2().int().positive().default(8),
22534
+ residency_max_children: ResidencyMaxChildrenInputSchema.default(8),
22444
22535
  ttl_ms: number2().int().positive().default(86400000),
22445
22536
  state_dir: string2().optional(),
22446
22537
  reattach_on_reconcile: boolean2().optional(),
22538
+ resume_children: boolean2().default(true),
22447
22539
  warnings: OmoTaskWarningsSchema.default({ unavailable_categories: true }),
22448
22540
  wait: OmoTaskWaitSchema.default({ min_ms: 5000, default_ms: 60000, max_ms: 600000 }),
22449
22541
  team: OmoTaskTeamSettingsSchema.default({
@@ -22471,10 +22563,11 @@ var init_task = __esm(() => {
22471
22563
  provider_concurrency: record(string2(), number2().int().positive()).optional(),
22472
22564
  model_concurrency: record(string2(), number2().int().positive()).optional(),
22473
22565
  max_depth: number2().int().nonnegative().optional(),
22474
- residency_max_children: number2().int().positive().optional(),
22566
+ residency_max_children: ResidencyMaxChildrenInputSchema.optional(),
22475
22567
  ttl_ms: number2().int().positive().optional(),
22476
22568
  state_dir: string2().optional(),
22477
22569
  reattach_on_reconcile: boolean2().optional(),
22570
+ resume_children: boolean2().optional(),
22478
22571
  warnings: OmoTaskWarningsLayerSchema.optional(),
22479
22572
  wait: OmoTaskWaitLayerSchema.optional(),
22480
22573
  team: OmoTaskTeamSettingsLayerSchema.optional()
@@ -22539,6 +22632,7 @@ var init_config = __esm(() => {
22539
22632
  init_agent();
22540
22633
  init_category();
22541
22634
  init_codegraph();
22635
+ init_memory();
22542
22636
  init_model_catalog();
22543
22637
  init_task();
22544
22638
  init_team();
@@ -22549,7 +22643,8 @@ var init_config = __esm(() => {
22549
22643
  codegraph: OmoCodegraphSettingsLayerSchema.optional(),
22550
22644
  task: OmoTaskSettingsLayerSchema.optional(),
22551
22645
  teams: OmoTeamsConfigLayerSchema.optional(),
22552
- models: OmoModelCatalogLayerSchema.optional()
22646
+ models: OmoModelCatalogLayerSchema.optional(),
22647
+ memory: OmoMemorySettingsLayerSchema.optional()
22553
22648
  }).strict();
22554
22649
  OmoConfigProfileSchema = object({
22555
22650
  categories: OmoCategoriesConfigSchema.optional(),
@@ -22558,6 +22653,7 @@ var init_config = __esm(() => {
22558
22653
  task: OmoTaskSettingsLayerSchema.optional(),
22559
22654
  teams: OmoTeamsConfigLayerSchema.optional(),
22560
22655
  models: OmoModelCatalogLayerSchema.optional(),
22656
+ memory: OmoMemorySettingsLayerSchema.optional(),
22561
22657
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22562
22658
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22563
22659
  "[codex]": OmoTypedHarnessConfigSchema.optional()
@@ -22570,6 +22666,7 @@ var init_config = __esm(() => {
22570
22666
  task: OmoTaskSettingsSchema.optional(),
22571
22667
  teams: OmoTeamsConfigSchema.optional(),
22572
22668
  models: OmoModelCatalogSchema.optional(),
22669
+ memory: OmoMemorySettingsSchema.optional(),
22573
22670
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22574
22671
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22575
22672
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
@@ -22585,6 +22682,7 @@ var init_config = __esm(() => {
22585
22682
  task: OmoTaskSettingsLayerSchema.optional(),
22586
22683
  teams: OmoTeamsConfigLayerSchema.optional(),
22587
22684
  models: OmoModelCatalogLayerSchema.optional(),
22685
+ memory: OmoMemorySettingsLayerSchema.optional(),
22588
22686
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22589
22687
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22590
22688
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
@@ -22602,6 +22700,7 @@ var init_schema = __esm(() => {
22602
22700
  init_config();
22603
22701
  init_fallback_models();
22604
22702
  init_harness();
22703
+ init_memory();
22605
22704
  init_model_catalog();
22606
22705
  init_model_ref();
22607
22706
  init_task();
@@ -22966,7 +23065,7 @@ var init_loader = __esm(() => {
22966
23065
  agents: {},
22967
23066
  categories: {},
22968
23067
  codegraph: OmoCodegraphSettingsSchema.parse({}),
22969
- task: OmoTaskSettingsSchema.parse({}),
23068
+ task: resolveOmoTaskSettings({}),
22970
23069
  teams: {}
22971
23070
  };
22972
23071
  });
@@ -23338,6 +23437,21 @@ var init_plain_object = __esm(() => {
23338
23437
  DANGEROUS_KEYS3 = new Set(["__proto__", "constructor", "prototype"]);
23339
23438
  });
23340
23439
 
23440
+ // packages/omo-config-core/src/migration/backup-move.ts
23441
+ function isCrossDeviceError(error51) {
23442
+ return error51 instanceof Error && Reflect.get(error51, "code") === "EXDEV";
23443
+ }
23444
+ function moveMigrationBackup(fileSystem, sourcePath, backupPath) {
23445
+ try {
23446
+ fileSystem.renameSync(sourcePath, backupPath);
23447
+ } catch (error51) {
23448
+ if (!isCrossDeviceError(error51))
23449
+ throw error51;
23450
+ fileSystem.copyFileSync(sourcePath, backupPath);
23451
+ fileSystem.unlinkSync(sourcePath);
23452
+ }
23453
+ }
23454
+
23341
23455
  // packages/omo-config-core/src/migration/merge.ts
23342
23456
  function displayValue(value) {
23343
23457
  const encoded = JSON.stringify(value);
@@ -23871,7 +23985,7 @@ function resumeMigrationJournal(input) {
23871
23985
  if (input.fileSystem.existsSync(move.to)) {
23872
23986
  throw new MigrationTransactionError(`Migration backup path already exists: ${move.to}`);
23873
23987
  }
23874
- input.fileSystem.renameSync(move.from, move.to);
23988
+ moveMigrationBackup(input.fileSystem, move.from, move.to);
23875
23989
  } else if (!input.fileSystem.existsSync(move.to)) {
23876
23990
  throw new MigrationTransactionError(`Migration source and backup are both missing: ${move.from}`);
23877
23991
  }
@@ -23999,7 +24113,7 @@ function executePlan(input) {
23999
24113
  input.renewLock();
24000
24114
  if (fileSystem.existsSync(move.to))
24001
24115
  throw new MigrationTransactionError(`Migration backup path already exists: ${move.to}`);
24002
- fileSystem.renameSync(move.from, move.to);
24116
+ moveMigrationBackup(fileSystem, move.from, move.to);
24003
24117
  input.onBoundary?.("source-moved");
24004
24118
  Object.assign(targetRecorded, { completedMoves: [...targetRecorded.completedMoves, move.from] });
24005
24119
  writeMigrationJournal(targetRecorded, fileSystem, env, input.process, input.clock);
@@ -24099,94 +24213,12 @@ function sgBinaryName(platform = process.platform) {
24099
24213
  }
24100
24214
  var init_sg_manifest = () => {};
24101
24215
 
24102
- // packages/utils/src/ast-grep/sg-provisioner.ts
24103
- var init_sg_provisioner = () => {};
24104
-
24105
- // packages/utils/src/ast-grep/types.ts
24106
- var SG_PATH_ENV_KEY = "OMO_AST_GREP_SG_PATH";
24107
-
24108
- // packages/utils/src/ast-grep/sg-resolver.ts
24109
- import { execFileSync as execFileSync2 } from "child_process";
24110
- import { existsSync as existsSync5, statSync as statSync2 } from "fs";
24111
- import { join as join8 } from "path";
24112
- function nonEmptyValue(value) {
24113
- const trimmed = value?.trim();
24114
- return trimmed === undefined || trimmed.length === 0 ? null : trimmed;
24115
- }
24116
- function defaultFileExists(filePath) {
24117
- if (!existsSync5(filePath))
24118
- return false;
24119
- try {
24120
- const stats = statSync2(filePath);
24121
- return stats.isFile() && stats.size > 0;
24122
- } catch (error51) {
24123
- if (error51 instanceof Error)
24124
- return false;
24125
- return false;
24126
- }
24127
- }
24128
- function defaultVersionProbe(binaryPath) {
24129
- return String(execFileSync2(binaryPath, ["--version"], {
24130
- encoding: "utf8",
24131
- stdio: ["ignore", "pipe", "ignore"],
24132
- timeout: 5000
24133
- }));
24134
- }
24135
- function isAstGrepVersionOutput(output) {
24136
- return output.toLowerCase().includes("ast-grep");
24137
- }
24138
- function hasAstGrepVersion(binaryPath, runVersionProbeSync) {
24139
- try {
24140
- return isAstGrepVersionOutput(runVersionProbeSync(binaryPath));
24141
- } catch (error51) {
24142
- if (error51 instanceof Error)
24143
- return false;
24144
- return false;
24145
- }
24146
- }
24147
- function pathCommandCandidates() {
24148
- return ["ast-grep", "sg"];
24149
- }
24150
- function findSgBinarySync(options = {}) {
24151
- const env = options.env ?? process.env;
24152
- const platform = options.platform ?? process.platform;
24153
- const fileExists = options.fileExists ?? defaultFileExists;
24154
- const runVersionProbeSync = options.runVersionProbeSync ?? defaultVersionProbe;
24155
- const which2 = options.which ?? bunWhich;
24156
- try {
24157
- const envOverride = nonEmptyValue(env[SG_PATH_ENV_KEY]);
24158
- if (envOverride !== null && fileExists(envOverride))
24159
- return envOverride;
24160
- if (options.runtimeDir !== undefined) {
24161
- const runtimeCandidate = join8(options.runtimeDir, sgBinaryName(platform));
24162
- if (fileExists(runtimeCandidate))
24163
- return runtimeCandidate;
24164
- }
24165
- for (const commandName of pathCommandCandidates()) {
24166
- const pathCandidate = which2(commandName);
24167
- if (pathCandidate === null || !fileExists(pathCandidate))
24168
- continue;
24169
- if (commandName !== "sg" || hasAstGrepVersion(pathCandidate, runVersionProbeSync))
24170
- return pathCandidate;
24171
- }
24172
- return null;
24173
- } catch (error51) {
24174
- if (error51 instanceof Error)
24175
- return null;
24176
- return null;
24177
- }
24178
- }
24179
- var init_sg_resolver = __esm(() => {
24180
- init_which();
24181
- init_sg_manifest();
24182
- });
24183
-
24184
24216
  // packages/utils/src/ast-grep/install-script.ts
24185
24217
  import { spawn as spawn3 } from "child_process";
24186
- import { existsSync as existsSync6 } from "fs";
24187
- import { join as join9 } from "path";
24218
+ import { existsSync as existsSync5 } from "fs";
24219
+ import { join as join8 } from "path";
24188
24220
  function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
24189
- return join9(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
24221
+ return join8(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
24190
24222
  }
24191
24223
  function isMissingExecutable(error51) {
24192
24224
  if (!("code" in error51))
@@ -24224,7 +24256,7 @@ function defaultSpawnProcess(command, args, options) {
24224
24256
  };
24225
24257
  }
24226
24258
  function scriptPathForPlatform(skillDir, platform) {
24227
- return join9(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
24259
+ return join8(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
24228
24260
  }
24229
24261
  function invocationsForPlatform(scriptPath, platform) {
24230
24262
  if (platform !== "win32")
@@ -24252,7 +24284,7 @@ function failedReason(outcome) {
24252
24284
  }
24253
24285
  async function runAstGrepSkillInstall(options) {
24254
24286
  const platform = options.platform ?? process.platform;
24255
- const fileExists = options.fileExists ?? existsSync6;
24287
+ const fileExists = options.fileExists ?? existsSync5;
24256
24288
  const scriptPath = scriptPathForPlatform(options.skillDir, platform);
24257
24289
  if (!fileExists(scriptPath))
24258
24290
  return { kind: "skipped", reason: `missing ${scriptPath}` };
@@ -24286,8 +24318,225 @@ var init_install_script = __esm(() => {
24286
24318
  init_sg_manifest();
24287
24319
  });
24288
24320
 
24321
+ // packages/utils/src/ast-grep/types.ts
24322
+ var SG_PATH_ENV_KEY = "OMO_AST_GREP_SG_PATH", SG_BINARY_NOT_FOUND = "BINARY_NOT_FOUND";
24323
+
24324
+ // packages/utils/src/ast-grep/sg-candidates.ts
24325
+ import { homedir } from "os";
24326
+ import { join as join9 } from "path";
24327
+ function nonEmptyValue(value) {
24328
+ const trimmed = value?.trim();
24329
+ return trimmed === undefined || trimmed.length === 0 ? null : trimmed;
24330
+ }
24331
+ function astGrepBinaryName(platform) {
24332
+ return platform === "win32" ? "ast-grep.exe" : "ast-grep";
24333
+ }
24334
+ function candidate(tier, path3) {
24335
+ return { path: path3, tier };
24336
+ }
24337
+ function envOverrideCandidates(env) {
24338
+ const override = nonEmptyValue(env[SG_PATH_ENV_KEY]);
24339
+ return override === null ? [] : [candidate("env-override", override)];
24340
+ }
24341
+ function omoRuntimeCandidates(options) {
24342
+ const binaryName = sgBinaryName(options.platform);
24343
+ const slug = runtimeSlug(options.platform, options.arch);
24344
+ const paths2 = [];
24345
+ if (options.runtimeDir !== undefined)
24346
+ paths2.push(join9(options.runtimeDir, binaryName));
24347
+ const codexHome = nonEmptyValue(options.env["CODEX_HOME"]);
24348
+ if (codexHome !== null)
24349
+ paths2.push(join9(codexHome, "runtime", "ast-grep", slug, binaryName));
24350
+ paths2.push(join9(options.homeDir, ".omo", "runtime", "ast-grep", slug, binaryName));
24351
+ return paths2.map((path3) => candidate("omo-runtime", path3));
24352
+ }
24353
+ function skillBinCandidates(options) {
24354
+ const names = [astGrepBinaryName(options.platform), sgBinaryName(options.platform)];
24355
+ const directories = [];
24356
+ const cacheDir = nonEmptyValue(options.env[AST_GREP_BIN_DIR_ENV_KEY]);
24357
+ if (cacheDir !== null)
24358
+ directories.push(cacheDir);
24359
+ if (options.packageDir !== undefined)
24360
+ directories.push(join9(options.packageDir, "bin"));
24361
+ return directories.flatMap((directory) => names.map((name) => candidate("skill-bin", join9(directory, name))));
24362
+ }
24363
+ function homebrewCandidates(platform) {
24364
+ const prefixes = platform === "darwin" || platform === "linux" || platform === "win32" ? HOMEBREW_PREFIXES[platform] : [];
24365
+ const names = [astGrepBinaryName(platform), sgBinaryName(platform)];
24366
+ return prefixes.flatMap((prefix) => names.map((name) => candidate("homebrew", join9(prefix, name))));
24367
+ }
24368
+ function planSgCandidates(options) {
24369
+ const env = options.env ?? process.env;
24370
+ const platform = options.platform ?? process.platform;
24371
+ const arch = options.arch ?? process.arch;
24372
+ const homeDir = options.homeDir ?? homedir();
24373
+ return {
24374
+ afterPath: homebrewCandidates(platform),
24375
+ beforePath: [
24376
+ ...envOverrideCandidates(env),
24377
+ ...omoRuntimeCandidates({ arch, env, homeDir, platform, runtimeDir: options.runtimeDir }),
24378
+ ...skillBinCandidates({ env, packageDir: options.packageDir, platform })
24379
+ ],
24380
+ pathCommands: ["ast-grep", "sg"]
24381
+ };
24382
+ }
24383
+ var HOMEBREW_PREFIXES;
24384
+ var init_sg_candidates = __esm(() => {
24385
+ init_install_script();
24386
+ init_sg_manifest();
24387
+ HOMEBREW_PREFIXES = {
24388
+ darwin: ["/opt/homebrew/bin", "/usr/local/bin"],
24389
+ linux: ["/home/linuxbrew/.linuxbrew/bin", "/usr/local/bin"],
24390
+ win32: []
24391
+ };
24392
+ });
24393
+
24394
+ // packages/utils/src/ast-grep/sg-install-hints.ts
24395
+ function platformHints(platform) {
24396
+ if (platform === "darwin")
24397
+ return DARWIN_HINTS;
24398
+ if (platform === "win32")
24399
+ return WIN32_HINTS;
24400
+ return LINUX_HINTS;
24401
+ }
24402
+ function sgInstallHints(platform = process.platform) {
24403
+ return [...platformHints(platform), OMO_PROVISION_HINT, ENV_OVERRIDE_HINT];
24404
+ }
24405
+ function sgBinaryNotFoundMessage(platform = process.platform) {
24406
+ return `ast-grep binary not found for ${platform}: no candidate passed the --version probe across the env override, OMO runtime, skill bin cache, PATH, or Homebrew prefixes.`;
24407
+ }
24408
+ var OMO_PROVISION_HINT = "Start an OMO session so the bundled ast-grep skill provisions the pinned runtime automatically", ENV_OVERRIDE_HINT, DARWIN_HINTS, LINUX_HINTS, WIN32_HINTS;
24409
+ var init_sg_install_hints = __esm(() => {
24410
+ ENV_OVERRIDE_HINT = `Or point ${SG_PATH_ENV_KEY} at an existing ast-grep binary`;
24411
+ DARWIN_HINTS = [
24412
+ "brew install ast-grep",
24413
+ "npm install -g @ast-grep/cli",
24414
+ "cargo install ast-grep --locked"
24415
+ ];
24416
+ LINUX_HINTS = [
24417
+ "npm install -g @ast-grep/cli",
24418
+ "cargo install ast-grep --locked",
24419
+ "brew install ast-grep # linuxbrew"
24420
+ ];
24421
+ WIN32_HINTS = [
24422
+ "scoop install main/ast-grep",
24423
+ "winget install ast-grep",
24424
+ "choco install ast-grep",
24425
+ "npm install -g @ast-grep/cli"
24426
+ ];
24427
+ });
24428
+
24429
+ // packages/utils/src/ast-grep/sg-provisioner.ts
24430
+ var init_sg_provisioner = () => {};
24431
+
24432
+ // packages/utils/src/ast-grep/sg-resolver.ts
24433
+ import { execFileSync as execFileSync2 } from "child_process";
24434
+ import { existsSync as existsSync6, statSync as statSync2 } from "fs";
24435
+ function cacheFingerprint(options, plan) {
24436
+ return JSON.stringify([
24437
+ options.platform ?? process.platform,
24438
+ options.arch ?? process.arch,
24439
+ plan.beforePath.map((candidate2) => candidate2.path)
24440
+ ]);
24441
+ }
24442
+ function defaultFileExists(filePath) {
24443
+ if (!existsSync6(filePath))
24444
+ return false;
24445
+ try {
24446
+ const stats = statSync2(filePath);
24447
+ return stats.isFile() && stats.size > 0;
24448
+ } catch {
24449
+ return false;
24450
+ }
24451
+ }
24452
+ function defaultVersionProbe(binaryPath) {
24453
+ return String(execFileSync2(binaryPath, ["--version"], {
24454
+ encoding: "utf8",
24455
+ stdio: ["ignore", "pipe", "ignore"],
24456
+ timeout: SG_VERSION_PROBE_TIMEOUT_MS
24457
+ }));
24458
+ }
24459
+ function probePasses(binaryPath, deps) {
24460
+ try {
24461
+ return deps.runVersionProbeSync(binaryPath).toLowerCase().includes("ast-grep");
24462
+ } catch {
24463
+ return false;
24464
+ }
24465
+ }
24466
+ function acceptsCandidate(binaryPath, deps) {
24467
+ return deps.fileExists(binaryPath) && probePasses(binaryPath, deps);
24468
+ }
24469
+ function firstAccepted(candidates, deps) {
24470
+ for (const candidate2 of candidates) {
24471
+ if (acceptsCandidate(candidate2.path, deps))
24472
+ return { found: true, path: candidate2.path, tier: candidate2.tier };
24473
+ }
24474
+ return null;
24475
+ }
24476
+ function pathCandidates(commands, deps) {
24477
+ const resolved = [];
24478
+ for (const commandName of commands) {
24479
+ const found = deps.which(commandName);
24480
+ if (found !== null)
24481
+ resolved.push({ path: found, tier: "path" });
24482
+ }
24483
+ return resolved;
24484
+ }
24485
+ function notFound(platform) {
24486
+ return {
24487
+ error: { code: SG_BINARY_NOT_FOUND, hints: sgInstallHints(platform), message: sgBinaryNotFoundMessage(platform) },
24488
+ found: false
24489
+ };
24490
+ }
24491
+ function cacheIsStillValid(resolution2, deps, revalidate) {
24492
+ if (!resolution2.found)
24493
+ return false;
24494
+ if (!deps.fileExists(resolution2.path))
24495
+ return false;
24496
+ return !revalidate || probePasses(resolution2.path, deps);
24497
+ }
24498
+ function resolverDeps(options) {
24499
+ return {
24500
+ fileExists: options.fileExists ?? defaultFileExists,
24501
+ platform: options.platform ?? process.platform,
24502
+ runVersionProbeSync: options.runVersionProbeSync ?? defaultVersionProbe,
24503
+ which: options.which ?? bunWhich
24504
+ };
24505
+ }
24506
+ function resolveSgBinarySync(options = {}) {
24507
+ const deps = resolverDeps(options);
24508
+ const useCache = options.cache ?? true;
24509
+ try {
24510
+ const plan = planSgCandidates(options);
24511
+ const fingerprint = cacheFingerprint(options, plan);
24512
+ if (useCache && cacheEntry !== null && cacheEntry.fingerprint === fingerprint) {
24513
+ if (cacheIsStillValid(cacheEntry.resolution, deps, options.revalidate ?? false))
24514
+ return cacheEntry.resolution;
24515
+ cacheEntry = null;
24516
+ }
24517
+ const resolution2 = firstAccepted(plan.beforePath, deps) ?? firstAccepted(pathCandidates(plan.pathCommands, deps), deps) ?? firstAccepted(plan.afterPath, deps) ?? notFound(deps.platform);
24518
+ if (useCache && resolution2.found)
24519
+ cacheEntry = { fingerprint, resolution: resolution2 };
24520
+ return resolution2;
24521
+ } catch {
24522
+ return notFound(deps.platform);
24523
+ }
24524
+ }
24525
+ function findSgBinarySync(options = {}) {
24526
+ const resolution2 = resolveSgBinarySync(options);
24527
+ return resolution2.found ? resolution2.path : null;
24528
+ }
24529
+ var SG_VERSION_PROBE_TIMEOUT_MS = 5000, cacheEntry = null;
24530
+ var init_sg_resolver = __esm(() => {
24531
+ init_which();
24532
+ init_sg_candidates();
24533
+ init_sg_install_hints();
24534
+ });
24535
+
24289
24536
  // packages/utils/src/ast-grep/index.ts
24290
24537
  var init_ast_grep = __esm(() => {
24538
+ init_sg_candidates();
24539
+ init_sg_install_hints();
24291
24540
  init_sg_manifest();
24292
24541
  init_sg_provisioner();
24293
24542
  init_sg_resolver();
@@ -24295,7 +24544,7 @@ var init_ast_grep = __esm(() => {
24295
24544
  });
24296
24545
 
24297
24546
  // packages/utils/src/classify-path-environment.ts
24298
- import { homedir } from "os";
24547
+ import { homedir as homedir2 } from "os";
24299
24548
  import path3 from "path";
24300
24549
  function normalizeInputPath(absolutePath) {
24301
24550
  return absolutePath.replaceAll("\\", "/");
@@ -24320,7 +24569,7 @@ function classifyPathEnvironment(absolutePath) {
24320
24569
  if (normalizedPath.startsWith("/Users/") && (normalizedPath.includes("/Desktop/") || normalizedPath.endsWith("/Desktop") || normalizedPath.includes("/Documents/") || normalizedPath.endsWith("/Documents"))) {
24321
24570
  return "desktop-sync";
24322
24571
  }
24323
- const normalizedHome = normalizeInputPath(homedir());
24572
+ const normalizedHome = normalizeInputPath(homedir2());
24324
24573
  const desktopPath = normalizeInputPath(path3.join(normalizedHome, "Desktop"));
24325
24574
  const documentsPath = normalizeInputPath(path3.join(normalizedHome, "Documents"));
24326
24575
  if (isUnderPath(normalizedPath, desktopPath) || isUnderPath(normalizedPath, documentsPath)) {
@@ -24467,16 +24716,16 @@ function defaultNodeRuntime(env, fileExists, which2, nodeVersion) {
24467
24716
  }
24468
24717
  const candidates = [
24469
24718
  ...isNodeExecutableName(process.execPath) ? [process.execPath] : [],
24470
- ...CODEGRAPH_NODE_CANDIDATES.map((commandName) => which2(commandName)).filter((candidate) => candidate !== null),
24471
- ...CODEGRAPH_NODE_PATH_CANDIDATES.filter((candidate) => fileExists(candidate))
24719
+ ...CODEGRAPH_NODE_CANDIDATES.map((commandName) => which2(commandName)).filter((candidate2) => candidate2 !== null),
24720
+ ...CODEGRAPH_NODE_PATH_CANDIDATES.filter((candidate2) => fileExists(candidate2))
24472
24721
  ];
24473
24722
  const seen = new Set;
24474
- for (const candidate of candidates) {
24475
- if (seen.has(candidate))
24723
+ for (const candidate2 of candidates) {
24724
+ if (seen.has(candidate2))
24476
24725
  continue;
24477
- seen.add(candidate);
24478
- if (supportsCodegraphNodeRuntime(candidate, env, nodeVersion))
24479
- return candidate;
24726
+ seen.add(candidate2);
24727
+ if (supportsCodegraphNodeRuntime(candidate2, env, nodeVersion))
24728
+ return candidate2;
24480
24729
  }
24481
24730
  return null;
24482
24731
  }
@@ -25573,7 +25822,7 @@ function hasObjectSessionPath(input) {
25573
25822
  }
25574
25823
  function isObjectPathTypeError(error51) {
25575
25824
  const message = error51 instanceof Error ? error51.message : typeof error51 === "string" ? error51 : "";
25576
- return message.includes('The "path" property must be of type string') && message.includes("got object");
25825
+ return message.includes('The "path" property must be of type string') && (message.includes("got object") || message.includes("got undefined"));
25577
25826
  }
25578
25827
  async function dispatchWithPathCompatibility(dispatch, input) {
25579
25828
  try {
@@ -26220,7 +26469,26 @@ var init_model_requirements = __esm(() => {
26220
26469
  });
26221
26470
 
26222
26471
  // packages/model-core/src/model-family-detectors.ts
26223
- var init_model_family_detectors = () => {};
26472
+ function extractModelName(model) {
26473
+ return model.includes("/") ? model.split("/").pop() ?? model : model;
26474
+ }
26475
+ function isClaudeOpus47OrLaterModel(model) {
26476
+ const modelName = extractModelName(model).toLowerCase().replaceAll(".", "-");
26477
+ if (modelName.includes("claude-fable"))
26478
+ return true;
26479
+ const match = CLAUDE_OPUS_VERSION_RE.exec(modelName);
26480
+ if (!match)
26481
+ return false;
26482
+ const major = Number(match[1]);
26483
+ const minor = match[2] === undefined ? 0 : Number(match[2]);
26484
+ if (Number.isNaN(major) || Number.isNaN(minor))
26485
+ return false;
26486
+ return major > 4 || major === 4 && minor >= 7;
26487
+ }
26488
+ var CLAUDE_OPUS_VERSION_RE;
26489
+ var init_model_family_detectors = __esm(() => {
26490
+ CLAUDE_OPUS_VERSION_RE = /claude-opus-(\d+)(?:-(\d+))?/;
26491
+ });
26224
26492
 
26225
26493
  // packages/model-core/src/model-capability-aliases.ts
26226
26494
  function normalizeLookupModelID(modelID) {
@@ -26318,9 +26586,83 @@ function normalizeModelID(modelID) {
26318
26586
  return modelID.replace(/\.(\d+)/g, "-$1");
26319
26587
  }
26320
26588
 
26589
+ // packages/model-core/src/reasoning-level.ts
26590
+ function isReasoningLevelOrAuto(value) {
26591
+ return REASONING_LEVEL_OR_AUTO_SET2.has(value);
26592
+ }
26593
+ function clampReasoningLevel(value, allowed) {
26594
+ const ladder = REASONING_LEVELS2;
26595
+ const requestedIndex = ladder.indexOf(value);
26596
+ if (requestedIndex === -1)
26597
+ return;
26598
+ for (let index = requestedIndex;index >= 0; index -= 1) {
26599
+ const candidate2 = REASONING_LEVELS2[index];
26600
+ if (candidate2 !== undefined && allowed.includes(candidate2))
26601
+ return candidate2;
26602
+ }
26603
+ return;
26604
+ }
26605
+ function splitReasoningSuffix2(model, options) {
26606
+ if (typeof model !== "string")
26607
+ return { base: "" };
26608
+ const trimmed = model.trim();
26609
+ if (!trimmed)
26610
+ return { base: "" };
26611
+ const separatorIndex = trimmed.lastIndexOf(":");
26612
+ if (separatorIndex === -1)
26613
+ return { base: trimmed };
26614
+ const base = trimmed.slice(0, separatorIndex).trim();
26615
+ const token = trimmed.slice(separatorIndex + 1).trim().toLowerCase();
26616
+ if (!base || !isReasoningLevelOrAuto(token))
26617
+ return { base: trimmed };
26618
+ if (token === "max" && !(options?.allowMaxSuffix ?? base.includes("/")))
26619
+ return { base: trimmed };
26620
+ return { base, level: token };
26621
+ }
26622
+ var REASONING_LEVELS2, REASONING_AUTO2 = "auto", REASONING_LEVEL_SET2, REASONING_LEVEL_OR_AUTO_SET2;
26623
+ var init_reasoning_level = __esm(() => {
26624
+ REASONING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
26625
+ REASONING_LEVEL_SET2 = new Set(REASONING_LEVELS2);
26626
+ REASONING_LEVEL_OR_AUTO_SET2 = new Set([...REASONING_LEVELS2, REASONING_AUTO2]);
26627
+ });
26628
+
26629
+ // packages/model-core/src/model-string-parser.ts
26630
+ function parseVariantFromModelID(rawModelID, options) {
26631
+ if (typeof rawModelID !== "string") {
26632
+ return { modelID: "" };
26633
+ }
26634
+ const trimmedModelID = rawModelID.trim();
26635
+ if (!trimmedModelID) {
26636
+ return { modelID: "" };
26637
+ }
26638
+ const parenthesizedVariant = trimmedModelID.match(/^(.*)\(([^()]+)\)\s*$/);
26639
+ if (parenthesizedVariant) {
26640
+ const modelID = parenthesizedVariant[1]?.trim() ?? "";
26641
+ const variant = parenthesizedVariant[2]?.trim();
26642
+ return variant ? { modelID, variant } : { modelID };
26643
+ }
26644
+ const suffixedModel = splitReasoningSuffix2(trimmedModelID, options);
26645
+ if (suffixedModel.level) {
26646
+ return { modelID: suffixedModel.base, variant: suffixedModel.level };
26647
+ }
26648
+ const spaceVariant = trimmedModelID.match(/^(.*\S)\s+([a-z][a-z0-9_-]*)$/i);
26649
+ if (spaceVariant) {
26650
+ const modelID = spaceVariant[1]?.trim() ?? "";
26651
+ const variant = spaceVariant[2]?.trim().toLowerCase();
26652
+ if (variant) {
26653
+ return { modelID, variant };
26654
+ }
26655
+ }
26656
+ return { modelID: trimmedModelID };
26657
+ }
26658
+ var init_model_string_parser = __esm(() => {
26659
+ init_reasoning_level();
26660
+ });
26661
+
26321
26662
  // packages/model-core/src/model-capability-heuristics.ts
26322
26663
  function detectHeuristicModelFamily(modelID) {
26323
- const normalizedModelID = normalizeModelID(modelID).toLowerCase();
26664
+ const parsedModel = parseVariantFromModelID(modelID, { allowMaxSuffix: true });
26665
+ const normalizedModelID = normalizeModelID(parsedModel.modelID).toLowerCase();
26324
26666
  for (const definition of HEURISTIC_MODEL_FAMILY_REGISTRY) {
26325
26667
  if (definition.pattern?.test(normalizedModelID)) {
26326
26668
  return definition;
@@ -26333,6 +26675,7 @@ function detectHeuristicModelFamily(modelID) {
26333
26675
  }
26334
26676
  var HEURISTIC_MODEL_FAMILY_REGISTRY;
26335
26677
  var init_model_capability_heuristics = __esm(() => {
26678
+ init_model_string_parser();
26336
26679
  HEURISTIC_MODEL_FAMILY_REGISTRY = [
26337
26680
  {
26338
26681
  family: "claude-opus",
@@ -26346,11 +26689,19 @@ var init_model_capability_heuristics = __esm(() => {
26346
26689
  variants: ["low", "medium", "high"],
26347
26690
  supportsThinking: true
26348
26691
  },
26692
+ {
26693
+ family: "openai-deep-research",
26694
+ includes: ["o3-deep-research", "o4-mini-deep-research"],
26695
+ variants: ["low", "medium", "high"],
26696
+ reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
26697
+ supportsTemperature: true
26698
+ },
26349
26699
  {
26350
26700
  family: "openai-reasoning",
26351
26701
  pattern: /(?:^|\/)o\d(?:$|-)/,
26352
26702
  variants: ["low", "medium", "high"],
26353
- reasoningEfforts: ["none", "minimal", "low", "medium", "high"]
26703
+ reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
26704
+ supportsTemperature: false
26354
26705
  },
26355
26706
  {
26356
26707
  family: "gpt-5",
@@ -26394,7 +26745,13 @@ var init_model_capability_heuristics = __esm(() => {
26394
26745
  {
26395
26746
  family: "glm",
26396
26747
  includes: ["glm"],
26397
- variants: ["low", "medium", "high"]
26748
+ variants: ["low", "medium", "high", "max"],
26749
+ reasoningEfforts: ["high", "max"],
26750
+ reasoningEffortAliases: {
26751
+ low: "high",
26752
+ medium: "high",
26753
+ xhigh: "max"
26754
+ }
26398
26755
  },
26399
26756
  {
26400
26757
  family: "minimax",
@@ -26429,26 +26786,6 @@ var init_model_capability_heuristics = __esm(() => {
26429
26786
  // packages/model-core/src/model-capability-guardrails.ts
26430
26787
  var init_model_capability_guardrails = () => {};
26431
26788
 
26432
- // packages/model-core/src/reasoning-level.ts
26433
- function clampReasoningLevel(value, allowed) {
26434
- const ladder = REASONING_LEVELS2;
26435
- const requestedIndex = ladder.indexOf(value);
26436
- if (requestedIndex === -1)
26437
- return;
26438
- for (let index = requestedIndex;index >= 0; index -= 1) {
26439
- const candidate = REASONING_LEVELS2[index];
26440
- if (candidate !== undefined && allowed.includes(candidate))
26441
- return candidate;
26442
- }
26443
- return;
26444
- }
26445
- var REASONING_LEVELS2, REASONING_AUTO2 = "auto", REASONING_LEVEL_SET2, REASONING_LEVEL_OR_AUTO_SET2;
26446
- var init_reasoning_level = __esm(() => {
26447
- REASONING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
26448
- REASONING_LEVEL_SET2 = new Set(REASONING_LEVELS2);
26449
- REASONING_LEVEL_OR_AUTO_SET2 = new Set([...REASONING_LEVELS2, REASONING_AUTO2]);
26450
- });
26451
-
26452
26789
  // packages/model-core/src/model-settings-compatibility.ts
26453
26790
  function downgradeWithinLadder(value, allowed) {
26454
26791
  return clampReasoningLevel(value, allowed);
@@ -26516,12 +26853,14 @@ function resolveCompatibleModelSettings(input) {
26516
26853
  reasoningEffort = resolved.value;
26517
26854
  }
26518
26855
  let temperature = input.desired.temperature;
26519
- if (temperature !== undefined && input.capabilities?.supportsTemperature === false) {
26856
+ const metadataSupportsTemperature = input.capabilities?.supportsTemperature;
26857
+ const familyDisallowsTemperature = metadataSupportsTemperature === undefined && (isClaudeOpus47OrLaterModel(input.modelID) || family?.supportsTemperature === false);
26858
+ if (temperature !== undefined && (metadataSupportsTemperature === false || familyDisallowsTemperature)) {
26520
26859
  changes.push({
26521
26860
  field: "temperature",
26522
26861
  from: String(temperature),
26523
26862
  to: undefined,
26524
- reason: "unsupported-by-model-metadata"
26863
+ reason: metadataSupportsTemperature === false ? "unsupported-by-model-metadata" : "unsupported-by-model-family"
26525
26864
  });
26526
26865
  temperature = undefined;
26527
26866
  }
@@ -26570,6 +26909,7 @@ function resolveCompatibleModelSettings(input) {
26570
26909
  }
26571
26910
  var init_model_settings_compatibility = __esm(() => {
26572
26911
  init_model_capability_heuristics();
26912
+ init_model_family_detectors();
26573
26913
  init_reasoning_level();
26574
26914
  });
26575
26915
 
@@ -26650,9 +26990,6 @@ function normalizeFallbackModels(models2) {
26650
26990
  }
26651
26991
  var init_model_resolver = () => {};
26652
26992
 
26653
- // packages/model-core/src/model-string-parser.ts
26654
- var init_model_string_parser = () => {};
26655
-
26656
26993
  // packages/model-core/src/fallback-chain-from-models.ts
26657
26994
  var init_fallback_chain_from_models = () => {};
26658
26995
 
@@ -26968,14 +27305,89 @@ function getProviderOverride(providerID, modelID) {
26968
27305
  return;
26969
27306
  return GITHUB_COPILOT_GPT5_MODEL.test(normalizeLookupModelID2(modelID)) ? GITHUB_COPILOT_GPT5_OVERRIDE : undefined;
26970
27307
  }
27308
+ function stripSameProviderPrefix(providerID, modelID) {
27309
+ const prefix = `${providerID.trim()}/`;
27310
+ return prefix !== "/" && modelID.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase() ? modelID.slice(prefix.length) : undefined;
27311
+ }
27312
+ function buildLookupCandidates(providerID, modelID) {
27313
+ const bareModelID = parseVariantFromModelID(modelID, { allowMaxSuffix: true }).modelID;
27314
+ const candidates = [
27315
+ modelID,
27316
+ stripSameProviderPrefix(providerID, modelID),
27317
+ bareModelID,
27318
+ stripSameProviderPrefix(providerID, bareModelID)
27319
+ ];
27320
+ const uniqueCandidates = [];
27321
+ const seen = new Set;
27322
+ for (const candidate2 of candidates) {
27323
+ if (!candidate2 || seen.has(candidate2))
27324
+ continue;
27325
+ seen.add(candidate2);
27326
+ uniqueCandidates.push(candidate2);
27327
+ }
27328
+ return uniqueCandidates;
27329
+ }
27330
+ function findProviderMetadata(providerCache, providerID, modelID) {
27331
+ if (!providerCache)
27332
+ return;
27333
+ for (const candidate2 of buildLookupCandidates(providerID, modelID)) {
27334
+ const match = providerCache.findProviderModelMetadata(providerID, candidate2);
27335
+ if (match)
27336
+ return match;
27337
+ }
27338
+ return;
27339
+ }
27340
+ function findSnapshotEntry(snapshot, providerID, modelIDs) {
27341
+ if (!snapshot)
27342
+ return;
27343
+ const normalizedProviderID = providerID.trim();
27344
+ const providerSpecificCandidates = [];
27345
+ const generalCandidates = [];
27346
+ for (const modelID of modelIDs) {
27347
+ const strippedModelID = stripSameProviderPrefix(providerID, modelID);
27348
+ const unqualifiedModelID = strippedModelID ?? (modelID.includes("/") ? undefined : modelID);
27349
+ if (!unqualifiedModelID) {
27350
+ generalCandidates.push(...buildLookupCandidates(providerID, modelID));
27351
+ continue;
27352
+ }
27353
+ const bareModelID = parseVariantFromModelID(unqualifiedModelID, { allowMaxSuffix: true }).modelID;
27354
+ if (normalizedProviderID) {
27355
+ providerSpecificCandidates.push(`${normalizedProviderID}/${unqualifiedModelID}`, `${normalizedProviderID}/${bareModelID}`);
27356
+ }
27357
+ generalCandidates.push(unqualifiedModelID, bareModelID);
27358
+ }
27359
+ const seen = new Set;
27360
+ for (const candidate2 of [...providerSpecificCandidates, ...generalCandidates]) {
27361
+ if (seen.has(candidate2))
27362
+ continue;
27363
+ seen.add(candidate2);
27364
+ const entry = snapshot.models[candidate2];
27365
+ if (entry)
27366
+ return entry;
27367
+ }
27368
+ return;
27369
+ }
27370
+ function resolveCapabilityModelAlias(modelID, providerID) {
27371
+ const direct = resolveModelIDAlias(modelID, providerID);
27372
+ if (direct.source !== "canonical")
27373
+ return direct;
27374
+ const bareModelID = parseVariantFromModelID(modelID, { allowMaxSuffix: true }).modelID;
27375
+ if (bareModelID === modelID)
27376
+ return direct;
27377
+ const bareAlias = resolveModelIDAlias(bareModelID, providerID);
27378
+ return bareAlias.source === "canonical" ? direct : { ...bareAlias, requestedModelID: modelID };
27379
+ }
26971
27380
  function getModelCapabilities(input) {
26972
- const canonicalization = resolveModelIDAlias(input.modelID, input.providerID);
27381
+ const canonicalization = resolveCapabilityModelAlias(input.modelID, input.providerID);
26973
27382
  const override = getOverride(input.modelID);
26974
27383
  const providerOverride = getProviderOverride(input.providerID, canonicalization.canonicalModelID);
26975
- const runtimeModel = readRuntimeModel(input.runtimeModel ?? input.providerCache?.findProviderModelMetadata(input.providerID, input.modelID));
27384
+ const runtimeModel = readRuntimeModel(input.runtimeModel ?? findProviderMetadata(input.providerCache, input.providerID, input.modelID));
26976
27385
  const runtimeSnapshot = input.runtimeSnapshot;
26977
27386
  const bundledSnapshot = input.bundledSnapshot;
26978
- const snapshotEntry = runtimeSnapshot?.models?.[canonicalization.canonicalModelID] ?? bundledSnapshot?.models?.[canonicalization.canonicalModelID];
27387
+ const snapshotModelIDs = canonicalization.source === "canonical" ? [input.modelID, canonicalization.canonicalModelID] : [canonicalization.canonicalModelID, input.modelID];
27388
+ const runtimeSnapshotEntry = findSnapshotEntry(runtimeSnapshot, input.providerID, snapshotModelIDs);
27389
+ const bundledSnapshotEntry = findSnapshotEntry(bundledSnapshot, input.providerID, snapshotModelIDs);
27390
+ const snapshotEntry = runtimeSnapshotEntry ?? bundledSnapshotEntry;
26979
27391
  const heuristicFamily = detectHeuristicModelFamily(canonicalization.canonicalModelID);
26980
27392
  const runtimeVariants = readRuntimeModelVariants(runtimeModel);
26981
27393
  const runtimeReasoning = readRuntimeModelReasoningSupport(runtimeModel);
@@ -26985,7 +27397,7 @@ function getModelCapabilities(input) {
26985
27397
  const runtimeMaxOutputTokens = readRuntimeModelLimitOutput(runtimeModel);
26986
27398
  const runtimeToolCall = readRuntimeModelToolCallSupport(runtimeModel);
26987
27399
  const runtimeModalities = readRuntimeModelModalities(runtimeModel);
26988
- const snapshotSource = runtimeSnapshot?.models?.[canonicalization.canonicalModelID] ? "runtime-snapshot" : bundledSnapshot?.models?.[canonicalization.canonicalModelID] ? "bundled-snapshot" : "none";
27400
+ const snapshotSource = runtimeSnapshotEntry ? "runtime-snapshot" : bundledSnapshotEntry ? "bundled-snapshot" : "none";
26989
27401
  const familySource = snapshotEntry?.family ? "snapshot" : heuristicFamily?.family ? "heuristic" : "none";
26990
27402
  const variantsSource = runtimeVariants ? "runtime" : providerOverride?.variants ? "override" : override?.variants ? "override" : heuristicFamily?.variants ? "heuristic" : "none";
26991
27403
  const reasoningEffortsSource = providerOverride?.reasoningEfforts ? "override" : override?.reasoningEfforts ? "override" : heuristicFamily?.reasoningEfforts ? "heuristic" : "none";
@@ -27034,6 +27446,7 @@ var MODEL_ID_OVERRIDES, GITHUB_COPILOT_GPT5_MODEL, GITHUB_COPILOT_GPT5_OVERRIDE;
27034
27446
  var init_get_model_capabilities = __esm(() => {
27035
27447
  init_model_capability_aliases();
27036
27448
  init_model_capability_heuristics();
27449
+ init_model_string_parser();
27037
27450
  MODEL_ID_OVERRIDES = {};
27038
27451
  GITHUB_COPILOT_GPT5_MODEL = /(?:^|\/)gpt-5(?:[.-]|$)/;
27039
27452
  GITHUB_COPILOT_GPT5_OVERRIDE = {
@@ -27569,15 +27982,15 @@ var init_kimi_categories = __esm(() => {
27569
27982
  });
27570
27983
 
27571
27984
  // packages/omo-opencode/src/agents/types.ts
27572
- function extractModelName(model) {
27985
+ function extractModelName2(model) {
27573
27986
  return model.includes("/") ? model.split("/").pop() ?? model : model;
27574
27987
  }
27575
27988
  function isGpt5_5Model(model) {
27576
- const modelName = extractModelName(model).toLowerCase();
27989
+ const modelName = extractModelName2(model).toLowerCase();
27577
27990
  return modelName.includes("gpt-5.5") || modelName.includes("gpt-5-5");
27578
27991
  }
27579
27992
  function isGpt5_6Model(model) {
27580
- const modelName = extractModelName(model).toLowerCase();
27993
+ const modelName = extractModelName2(model).toLowerCase();
27581
27994
  return modelName.includes("gpt-5.6") || modelName.includes("gpt-5-6");
27582
27995
  }
27583
27996
  var init_types4 = () => {};
@@ -27789,7 +28202,7 @@ var init_migration3 = __esm(() => {
27789
28202
 
27790
28203
  // packages/omo-opencode/src/shared/opencode-config-dir.ts
27791
28204
  import { existsSync as existsSync8, realpathSync as realpathSync3 } from "fs";
27792
- import { homedir as homedir3 } from "os";
28205
+ import { homedir as homedir4 } from "os";
27793
28206
  import { join as join12, posix as posix4, resolve as resolve4, win32 } from "path";
27794
28207
  function isDevBuild(version2) {
27795
28208
  if (!version2)
@@ -27800,14 +28213,14 @@ function getTauriConfigDir(identifier) {
27800
28213
  const platform = process.platform;
27801
28214
  switch (platform) {
27802
28215
  case "darwin":
27803
- return join12(homedir3(), "Library", "Application Support", identifier);
28216
+ return join12(homedir4(), "Library", "Application Support", identifier);
27804
28217
  case "win32": {
27805
- const appData = process.env.APPDATA || join12(homedir3(), "AppData", "Roaming");
28218
+ const appData = process.env.APPDATA || join12(homedir4(), "AppData", "Roaming");
27806
28219
  return win32.join(appData, identifier);
27807
28220
  }
27808
28221
  case "linux":
27809
28222
  default: {
27810
- const xdgConfig = process.env.XDG_CONFIG_HOME || join12(homedir3(), ".config");
28223
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join12(homedir4(), ".config");
27811
28224
  return join12(xdgConfig, identifier);
27812
28225
  }
27813
28226
  }
@@ -27851,7 +28264,7 @@ function getWslLinuxHomeDir(windowsConfigRoot) {
27851
28264
  function getCliDefaultConfigDir() {
27852
28265
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
27853
28266
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment() && isWindowsUserConfigRoot(envXdgConfig);
27854
- const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join12(homedir3(), ".config");
28267
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join12(homedir4(), ".config");
27855
28268
  const configDir = isWslEnvironment() ? posix4.join(xdgConfig, "opencode") : join12(xdgConfig, "opencode");
27856
28269
  return resolveConfigPath(configDir);
27857
28270
  }
@@ -86670,7 +87083,7 @@ function toFallbackModelObject(entry, provider) {
86670
87083
  }
86671
87084
  function collectAvailableFallbacks(fallbackChain, availability) {
86672
87085
  const expandedFallbacks = fallbackChain.flatMap((entry) => entry.providers.filter((provider) => isProviderAvailable(provider, availability)).map((provider) => toFallbackModelObject(entry, provider)));
86673
- return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate) => candidate.model === entry.model && candidate.variant === entry.variant) === index);
87086
+ return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate2) => candidate2.model === entry.model && candidate2.variant === entry.variant) === index);
86674
87087
  }
86675
87088
  function attachFallbackModels(config3, fallbackChain, availability) {
86676
87089
  const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
@@ -86960,12 +87373,12 @@ function configRoots(options) {
86960
87373
  ];
86961
87374
  const seen = new Set;
86962
87375
  const result = [];
86963
- for (const candidate of candidates) {
86964
- const key = pathKey(candidate.path, options);
87376
+ for (const candidate2 of candidates) {
87377
+ const key = pathKey(candidate2.path, options);
86965
87378
  if (seen.has(key))
86966
87379
  continue;
86967
87380
  seen.add(key);
86968
- result.push({ ...candidate, path: canonicalPath(candidate.path, options) });
87381
+ result.push({ ...candidate2, path: canonicalPath(candidate2.path, options) });
86969
87382
  }
86970
87383
  return result;
86971
87384
  }
@@ -87109,10 +87522,10 @@ function historyValues(value) {
87109
87522
  return [];
87110
87523
  const values = [];
87111
87524
  for (const key of ["_migrations", "appliedMigrations"]) {
87112
- const candidate = value[key];
87113
- if (!Array.isArray(candidate))
87525
+ const candidate2 = value[key];
87526
+ if (!Array.isArray(candidate2))
87114
87527
  continue;
87115
- for (const item of candidate) {
87528
+ for (const item of candidate2) {
87116
87529
  if (typeof item === "string" && !values.includes(item))
87117
87530
  values.push(item);
87118
87531
  }
@@ -88219,20 +88632,20 @@ var init_config_manager = __esm(() => {
88219
88632
 
88220
88633
  // packages/telemetry-core/src/activity-state.ts
88221
88634
  import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as readFileSync12 } from "fs";
88222
- import { basename as basename9, join as join52 } from "path";
88635
+ import { basename as basename9, join as join53 } from "path";
88223
88636
  function resolveTelemetryStateDir(product, options = {}) {
88224
88637
  const dataDir = resolveXdgDataDir(product.cacheDirName, {
88225
88638
  env: options.env,
88226
88639
  osProvider: options.osProvider
88227
88640
  });
88228
- const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join52(options.env.XDG_DATA_HOME, product.cacheDirName);
88641
+ const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join53(options.env.XDG_DATA_HOME, product.cacheDirName);
88229
88642
  if (dataDir === xdgStateDir || xdgStateDir === undefined && basename9(dataDir) === product.cacheDirName) {
88230
88643
  return dataDir;
88231
88644
  }
88232
- return join52(dataDir, product.cacheDirName);
88645
+ return join53(dataDir, product.cacheDirName);
88233
88646
  }
88234
88647
  function getTelemetryActivityStateFilePath(stateDir) {
88235
- return join52(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
88648
+ return join53(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
88236
88649
  }
88237
88650
  function getDailyActiveCaptureState(input) {
88238
88651
  const state = readPostHogActivityState(input.stateDir, input.diagnostics);
@@ -88303,9 +88716,9 @@ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY =
88303
88716
 
88304
88717
  // packages/telemetry-core/src/diagnostics.ts
88305
88718
  import { appendFileSync as appendFileSync2, existsSync as existsSync27, mkdirSync as mkdirSync9, readFileSync as readFileSync13 } from "fs";
88306
- import { join as join53 } from "path";
88719
+ import { join as join54 } from "path";
88307
88720
  function getTelemetryDiagnosticsFilePath(diagnosticsDir) {
88308
- return join53(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
88721
+ return join54(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
88309
88722
  }
88310
88723
  function writeTelemetryDiagnostic(input, options) {
88311
88724
  const now = options.now ?? new Date;
@@ -88779,21 +89192,21 @@ var init_string_utils = () => {};
88779
89192
  function isPrimitive(value) {
88780
89193
  return value === null || typeof value != "object";
88781
89194
  }
88782
- function isBuiltin(candidate, className) {
88783
- return Object.prototype.toString.call(candidate) === `[object ${className}]`;
89195
+ function isBuiltin(candidate2, className) {
89196
+ return Object.prototype.toString.call(candidate2) === `[object ${className}]`;
88784
89197
  }
88785
89198
  function isErrorEvent(event) {
88786
89199
  return isBuiltin(event, "ErrorEvent");
88787
89200
  }
88788
- function isEvent(candidate) {
88789
- return typeof Event != "undefined" && isInstanceOf(candidate, Event);
89201
+ function isEvent(candidate2) {
89202
+ return typeof Event != "undefined" && isInstanceOf(candidate2, Event);
88790
89203
  }
88791
- function isPlainObject5(candidate) {
88792
- return isBuiltin(candidate, "Object");
89204
+ function isPlainObject5(candidate2) {
89205
+ return isBuiltin(candidate2, "Object");
88793
89206
  }
88794
- function isInstanceOf(candidate, base) {
89207
+ function isInstanceOf(candidate2, base) {
88795
89208
  try {
88796
- return candidate instanceof base;
89209
+ return candidate2 instanceof base;
88797
89210
  } catch {
88798
89211
  return false;
88799
89212
  }
@@ -89938,8 +90351,8 @@ class DOMExceptionCoercer {
89938
90351
  synthetic: false
89939
90352
  };
89940
90353
  }
89941
- getType(candidate) {
89942
- return this.isDOMError(candidate) ? "DOMError" : "DOMException";
90354
+ getType(candidate2) {
90355
+ return this.isDOMError(candidate2) ? "DOMError" : "DOMException";
89943
90356
  }
89944
90357
  getValue(err) {
89945
90358
  const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
@@ -90024,10 +90437,10 @@ class StringCoercer {
90024
90437
  synthetic: true
90025
90438
  };
90026
90439
  }
90027
- getInfos(candidate) {
90440
+ getInfos(candidate2) {
90028
90441
  let type = "Error";
90029
- let value = candidate;
90030
- const groups = candidate.match(ERROR_TYPES_PATTERN);
90442
+ let value = candidate2;
90443
+ const groups = candidate2.match(ERROR_TYPES_PATTERN);
90031
90444
  if (groups) {
90032
90445
  type = groups[1];
90033
90446
  value = groups[2];
@@ -90076,18 +90489,18 @@ var init_utils2 = () => {};
90076
90489
 
90077
90490
  // node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
90078
90491
  class ObjectCoercer {
90079
- match(candidate) {
90080
- return typeof candidate == "object" && candidate !== null;
90492
+ match(candidate2) {
90493
+ return typeof candidate2 == "object" && candidate2 !== null;
90081
90494
  }
90082
- coerce(candidate, ctx) {
90083
- const errorProperty = this.getErrorPropertyFromObject(candidate);
90495
+ coerce(candidate2, ctx) {
90496
+ const errorProperty = this.getErrorPropertyFromObject(candidate2);
90084
90497
  if (errorProperty)
90085
90498
  return ctx.apply(errorProperty);
90086
90499
  return {
90087
- type: this.getType(candidate),
90088
- value: this.getValue(candidate),
90500
+ type: this.getType(candidate2),
90501
+ value: this.getValue(candidate2),
90089
90502
  stack: ctx.syntheticException?.stack,
90090
- level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
90503
+ level: this.isSeverityLevel(candidate2.level) ? candidate2.level : "error",
90091
90504
  synthetic: true
90092
90505
  };
90093
90506
  }
@@ -90155,8 +90568,8 @@ var init_event_coercer = __esm(() => {
90155
90568
 
90156
90569
  // node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
90157
90570
  class PrimitiveCoercer {
90158
- match(candidate) {
90159
- return isPrimitive(candidate);
90571
+ match(candidate2) {
90572
+ return isPrimitive(candidate2);
90160
90573
  }
90161
90574
  coerce(value, ctx) {
90162
90575
  return {
@@ -94026,7 +94439,7 @@ var package_default2;
94026
94439
  var init_package2 = __esm(() => {
94027
94440
  package_default2 = {
94028
94441
  name: "@oh-my-opencode/omo-codex",
94029
- version: "4.19.4",
94442
+ version: "5.0.0-beta.2",
94030
94443
  type: "module",
94031
94444
  private: true,
94032
94445
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -94418,8 +94831,8 @@ import * as fs3 from "fs";
94418
94831
  import * as path8 from "path";
94419
94832
  function findPackageJsonUp(startPath) {
94420
94833
  try {
94421
- const stat6 = fs3.statSync(startPath);
94422
- let dir = stat6.isDirectory() ? startPath : path8.dirname(startPath);
94834
+ const stat7 = fs3.statSync(startPath);
94835
+ let dir = stat7.isDirectory() ? startPath : path8.dirname(startPath);
94423
94836
  for (let i = 0;i < 10; i++) {
94424
94837
  const pkgPath = path8.join(dir, "package.json");
94425
94838
  if (fs3.existsSync(pkgPath)) {
@@ -94540,10 +94953,10 @@ function getCachedVersion(options = {}) {
94540
94953
  log2("[auto-update-checker] Failed to resolve version from current directory:", err);
94541
94954
  }
94542
94955
  }
94543
- for (const candidate of packageJsonCandidates) {
94956
+ for (const candidate2 of packageJsonCandidates) {
94544
94957
  try {
94545
- if (fs6.existsSync(candidate)) {
94546
- return readPackageVersion(candidate);
94958
+ if (fs6.existsSync(candidate2)) {
94959
+ return readPackageVersion(candidate2);
94547
94960
  }
94548
94961
  } catch (err) {
94549
94962
  if (err instanceof Error) {
@@ -94995,20 +95408,20 @@ var init_update_toasts = __esm(() => {
94995
95408
  });
94996
95409
 
94997
95410
  // packages/omo-opencode/src/hooks/auto-update-checker/hook/background-update-check.ts
94998
- import { existsSync as existsSync45 } from "fs";
94999
- import { dirname as dirname26, join as join70 } from "path";
95411
+ import { existsSync as existsSync46 } from "fs";
95412
+ import { dirname as dirname28, join as join73 } from "path";
95000
95413
  import { fileURLToPath as fileURLToPath5 } from "url";
95001
95414
  function defaultGetModuleHostingWorkspace() {
95002
95415
  try {
95003
- const currentDir = dirname26(fileURLToPath5(import.meta.url));
95416
+ const currentDir = dirname28(fileURLToPath5(import.meta.url));
95004
95417
  const pkgJsonPath = findPackageJsonUp(currentDir);
95005
95418
  if (!pkgJsonPath)
95006
95419
  return null;
95007
- const pkgDir = dirname26(pkgJsonPath);
95008
- const nodeModulesDir = dirname26(pkgDir);
95420
+ const pkgDir = dirname28(pkgJsonPath);
95421
+ const nodeModulesDir = dirname28(pkgDir);
95009
95422
  if (nodeModulesDir.split(/[\\/]/).pop() !== "node_modules")
95010
95423
  return null;
95011
- return dirname26(nodeModulesDir);
95424
+ return dirname28(nodeModulesDir);
95012
95425
  } catch (error51) {
95013
95426
  if (error51 instanceof Error) {
95014
95427
  return null;
@@ -95149,8 +95562,8 @@ var init_background_update_check = __esm(() => {
95149
95562
  init_package_json_locator();
95150
95563
  init_update_toasts();
95151
95564
  defaultDeps4 = {
95152
- existsSync: existsSync45,
95153
- join: join70,
95565
+ existsSync: existsSync46,
95566
+ join: join73,
95154
95567
  runBunInstallWithDetails,
95155
95568
  log: log2,
95156
95569
  getOpenCodeCacheDir,
@@ -95313,7 +95726,7 @@ async function showSpinnerToast(ctx, version3, message) {
95313
95726
  duration: frameInterval + 50
95314
95727
  }
95315
95728
  }).catch(ignoreToastError);
95316
- await new Promise((resolve18) => setTimeout(resolve18, frameInterval));
95729
+ await new Promise((resolve20) => setTimeout(resolve20, frameInterval));
95317
95730
  }
95318
95731
  }
95319
95732
  var SISYPHUS_SPINNER;
@@ -95759,9 +96172,9 @@ function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
95759
96172
  }
95760
96173
 
95761
96174
  // packages/omo-codex/src/install/install-codex.ts
95762
- import { join as join54, resolve as resolve13 } from "path";
96175
+ import { join as join55, resolve as resolve13 } from "path";
95763
96176
  import { existsSync as existsSync28 } from "fs";
95764
- import { homedir as homedir5 } from "os";
96177
+ import { homedir as homedir6 } from "os";
95765
96178
 
95766
96179
  // packages/omo-codex/src/install/codex-cache-bins.ts
95767
96180
  import { chmod, lstat as lstat4, mkdir, readFile as readFile3, readdir as readdir2, readlink as readlink3, rm as rm3, stat as stat2, symlink, writeFile } from "fs/promises";
@@ -95930,6 +96343,11 @@ var LEGACY_CODEX_COMPONENT_BINS = [
95930
96343
  { name: "codex-telemetry", component: "telemetry" },
95931
96344
  { name: "codex-ultrawork", component: "ultrawork" }
95932
96345
  ];
96346
+ var LEGACY_CODEX_COMPONENT_BIN_NAMES = LEGACY_CODEX_COMPONENT_BINS.map((entry) => entry.name);
96347
+ function isLegacyCodexBinTarget(binName, target) {
96348
+ const entry = LEGACY_CODEX_COMPONENT_BINS.find((candidate2) => candidate2.name === binName);
96349
+ return entry !== undefined && isManagedLegacyComponentTarget(target, entry.component);
96350
+ }
95933
96351
  async function removeLegacyCodexComponentBins(binDir, platform) {
95934
96352
  for (const entry of LEGACY_CODEX_COMPONENT_BINS) {
95935
96353
  const linkPath = join24(binDir, platform === "win32" ? `${entry.name}.cmd` : entry.name);
@@ -95985,7 +96403,7 @@ function isNodeErrorWithCode2(error51) {
95985
96403
  // packages/omo-codex/src/install/codex-cache-runtime-wrapper.ts
95986
96404
  import { join as join25 } from "path";
95987
96405
  var RUNTIME_WRAPPER_MARKER = "OMO_GENERATED_RUNTIME_WRAPPER";
95988
- function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96406
+ function posixRuntimeWrapper(binName, cliPath, codexHome, binDir, nodeCliPath) {
95989
96407
  const ulwLoopBin = toPosixPath2(join25(binDir, "omo-ulw-loop"));
95990
96408
  const nodeCli = escapePosixDoubleQuoted(toPosixPath2(nodeCliPath));
95991
96409
  const escapedCliPath = escapePosixDoubleQuoted(toPosixPath2(cliPath));
@@ -95995,6 +96413,8 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
95995
96413
  "#!/bin/sh",
95996
96414
  `# ${RUNTIME_WRAPPER_MARKER}`,
95997
96415
  `export CODEX_HOME="\${CODEX_HOME:-${escapedCodexHome}}"`,
96416
+ `export OMO_INVOCATION_NAME=${binName}`,
96417
+ "export OMO_EDITION=codex",
95998
96418
  'if [ "$1" = "ulw-loop" ] && [ -x "' + escapedUlwLoopBin + '" ]; then',
95999
96419
  " shift",
96000
96420
  ' exec "' + escapedUlwLoopBin + '" ulw-loop "$@"',
@@ -96018,11 +96438,11 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96018
96438
  ` if [ -f "${nodeCli}" ] && command -v node >/dev/null 2>&1; then`,
96019
96439
  ` exec node "${nodeCli}" "$@"`,
96020
96440
  " fi",
96021
- ` echo "omo: bun runtime not found (checked PATH, ~/.bun/bin, /opt/homebrew/bin, /usr/local/bin) and the node fallback CLI is missing at ${nodeCli}; install bun from https://bun.sh, or reinstall omo and force the fallback with OMO_RUNTIME=node" >&2`,
96441
+ ` echo "${binName}: bun runtime not found (checked PATH, ~/.bun/bin, /opt/homebrew/bin, /usr/local/bin) and the node fallback CLI is missing at ${nodeCli}; install bun from https://bun.sh, or reinstall ${binName} and force the fallback with OMO_RUNTIME=node" >&2`,
96022
96442
  " exit 127",
96023
96443
  "fi",
96024
96444
  `if [ ! -f "${escapedCliPath}" ]; then`,
96025
- ` echo "omo: runtime target missing at ${escapedCliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui" >&2`,
96445
+ ` echo "${binName}: runtime target missing at ${escapedCliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui" >&2`,
96026
96446
  " exit 1",
96027
96447
  "fi",
96028
96448
  `exec "$BUN_BINARY" "${escapedCliPath}" "$@"`,
@@ -96030,12 +96450,14 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96030
96450
  ].join(`
96031
96451
  `);
96032
96452
  }
96033
- function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96453
+ function windowsRuntimeWrapper(binName, cliPath, codexHome, binDir, nodeCliPath) {
96034
96454
  const ulwLoopBin = join25(binDir, "omo-ulw-loop.cmd");
96035
96455
  return [
96036
96456
  "@echo off",
96037
96457
  `rem ${RUNTIME_WRAPPER_MARKER}`,
96038
96458
  `if not defined CODEX_HOME set "CODEX_HOME=${codexHome}"`,
96459
+ `set "OMO_INVOCATION_NAME=${binName}"`,
96460
+ 'set "OMO_EDITION=codex"',
96039
96461
  ...windowsNodeDiscoveryLines(),
96040
96462
  `if "%~1"=="ulw-loop" if exist "${ulwLoopBin}" (`,
96041
96463
  " shift /1",
@@ -96053,11 +96475,11 @@ function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96053
96475
  ` "%OMO_NODE_BINARY%" "${nodeCliPath}" %*`,
96054
96476
  " exit /b %ERRORLEVEL%",
96055
96477
  " )",
96056
- ` echo omo: bun runtime not found, no Node runtime was discovered from NODE_REPL_NODE_PATH or PATH, or the node fallback CLI is missing at ${nodeCliPath}; install bun from https://bun.sh or rerun LazyCodex install from Codex Desktop 1>&2`,
96478
+ ` echo ${binName}: bun runtime not found, no Node runtime was discovered from NODE_REPL_NODE_PATH or PATH, or the node fallback CLI is missing at ${nodeCliPath}; install bun from https://bun.sh or rerun LazyCodex install from Codex Desktop 1>&2`,
96057
96479
  " exit /b 127",
96058
96480
  ")",
96059
96481
  `if not exist "${cliPath}" (`,
96060
- ` echo omo: runtime target missing at ${cliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui 1>&2`,
96482
+ ` echo ${binName}: runtime target missing at ${cliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui 1>&2`,
96061
96483
  " exit /b 1",
96062
96484
  ")",
96063
96485
  `"%BUN_BINARY%" "${cliPath}" %*`,
@@ -96073,7 +96495,14 @@ function escapePosixDoubleQuoted(value) {
96073
96495
  }
96074
96496
 
96075
96497
  // packages/omo-codex/src/install/codex-cache-bins.ts
96076
- var RESERVED_NESTED_BIN_NAMES = new Set(["omo", "lazycodex", "lazycodex-ai", "oh-my-opencode", "oh-my-openagent"]);
96498
+ var RESERVED_NESTED_BIN_NAMES = new Set([
96499
+ "omo",
96500
+ "omo-agent-toolkit",
96501
+ "lazycodex",
96502
+ "lazycodex-ai",
96503
+ "oh-my-opencode",
96504
+ "oh-my-openagent"
96505
+ ]);
96077
96506
  async function linkCachedPluginBins(input) {
96078
96507
  const binLinks = await discoverPackageBins(input.pluginRoot);
96079
96508
  const platform = input.platform ?? process.platform;
@@ -96103,20 +96532,26 @@ async function removeCachedManagedNpmBinShims(pluginRoot) {
96103
96532
  }
96104
96533
  async function linkRootRuntimeBin(input) {
96105
96534
  const cliPath = join26(input.repoRoot, "dist", "cli", "index.js");
96106
- if (!await isFile(cliPath))
96535
+ const platform = input.platform ?? process.platform;
96536
+ const legacyPath = join26(input.binDir, platform === "win32" ? "omo.cmd" : "omo");
96537
+ if (!await isFile(cliPath)) {
96538
+ await removeGeneratedRuntimeWrapper(legacyPath);
96107
96539
  return null;
96540
+ }
96541
+ const binName = "omo-agent-toolkit";
96108
96542
  const nodeCliPath = join26(input.repoRoot, "dist", "cli-node", "index.js");
96109
- const platform = input.platform ?? process.platform;
96110
96543
  await mkdir(input.binDir, { recursive: true });
96111
96544
  if (platform === "win32") {
96112
- const linkPath2 = join26(input.binDir, "omo.cmd");
96113
- await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
96114
- return { name: "omo", path: linkPath2, target: cliPath };
96545
+ const linkPath2 = join26(input.binDir, `${binName}.cmd`);
96546
+ await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(binName, cliPath, input.codexHome, input.binDir, nodeCliPath));
96547
+ await removeGeneratedRuntimeWrapper(legacyPath);
96548
+ return { name: binName, path: linkPath2, target: cliPath };
96115
96549
  }
96116
- const linkPath = join26(input.binDir, "omo");
96117
- await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
96550
+ const linkPath = join26(input.binDir, binName);
96551
+ await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(binName, cliPath, input.codexHome, input.binDir, nodeCliPath));
96118
96552
  await chmod(linkPath, 493);
96119
- return { name: "omo", path: linkPath, target: cliPath };
96553
+ await removeGeneratedRuntimeWrapper(legacyPath);
96554
+ return { name: binName, path: linkPath, target: cliPath };
96120
96555
  }
96121
96556
  async function linkCachedPluginBin(binDir, link, platform) {
96122
96557
  if (platform === "win32") {
@@ -96229,6 +96664,29 @@ async function replaceRuntimeWrapper(linkPath, content) {
96229
96664
  await rm3(linkPath, { force: true });
96230
96665
  await writeFile(linkPath, content);
96231
96666
  }
96667
+ async function removeGeneratedRuntimeWrapper(path6) {
96668
+ try {
96669
+ const entry = await lstat4(path6);
96670
+ if (!entry.isFile() && !entry.isSymbolicLink())
96671
+ return;
96672
+ const content = await readGeneratedWrapperContent(path6);
96673
+ if (content.includes(RUNTIME_WRAPPER_MARKER))
96674
+ await rm3(path6, { force: true });
96675
+ } catch (error51) {
96676
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
96677
+ return;
96678
+ throw error51;
96679
+ }
96680
+ }
96681
+ async function readGeneratedWrapperContent(path6) {
96682
+ try {
96683
+ return await readFile3(path6, "utf8");
96684
+ } catch (error51) {
96685
+ if (isNodeErrorWithCode(error51) && (error51.code === "ENOENT" || error51.code === "EISDIR"))
96686
+ return "";
96687
+ throw error51;
96688
+ }
96689
+ }
96232
96690
  async function existingNonRuntimeWrapper(path6) {
96233
96691
  try {
96234
96692
  const stat3 = await lstat4(path6);
@@ -96304,7 +96762,7 @@ async function copyBundledMcpRuntimeDists(input) {
96304
96762
  }
96305
96763
  }
96306
96764
  function resolveBundledMcpRuntimeArg(pluginRoot, arg) {
96307
- const runtime4 = BUNDLED_MCP_RUNTIMES.find((candidate) => candidate.sourceArg === arg);
96765
+ const runtime4 = BUNDLED_MCP_RUNTIMES.find((candidate2) => candidate2.sourceArg === arg);
96308
96766
  return runtime4 ? join27(pluginRoot, runtime4.destinationArg) : null;
96309
96767
  }
96310
96768
  async function copyBundledMcpRuntimeDist(pluginRoot, sourceRoot, runtime4) {
@@ -96380,9 +96838,9 @@ function findNewestCachedCodexComponentCli(input) {
96380
96838
  return null;
96381
96839
  const versions2 = readdirSync6(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionNames).reverse();
96382
96840
  for (const version2 of versions2) {
96383
- const candidate = resolveCachedCodexComponentCliPath(join28(versionsRoot, version2), input.componentName);
96384
- if (existsSync24(candidate))
96385
- return candidate;
96841
+ const candidate2 = resolveCachedCodexComponentCliPath(join28(versionsRoot, version2), input.componentName);
96842
+ if (existsSync24(candidate2))
96843
+ return candidate2;
96386
96844
  }
96387
96845
  return null;
96388
96846
  }
@@ -97348,8 +97806,8 @@ function findUnquotedCharacter(line, target, startIndex) {
97348
97806
  }
97349
97807
  return -1;
97350
97808
  }
97351
- function tomlPathMatches(candidate, target) {
97352
- return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
97809
+ function tomlPathMatches(candidate2, target) {
97810
+ return candidate2.length === target.length && candidate2.every((part, index) => part === target[index]);
97353
97811
  }
97354
97812
  function replaceTomlAssignmentValue(line, assignmentIndex, value) {
97355
97813
  const newline = line.endsWith(`
@@ -99928,13 +100386,13 @@ function processIsRunning(pid) {
99928
100386
  }
99929
100387
 
99930
100388
  // packages/omo-codex/src/install/codex-installer-bin-dir.ts
99931
- import { homedir as homedir4 } from "os";
100389
+ import { homedir as homedir5 } from "os";
99932
100390
  import { join as join48, resolve as resolve12 } from "path";
99933
100391
  function resolveCodexInstallerBinDir(input) {
99934
100392
  const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
99935
100393
  if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
99936
100394
  return resolve12(explicitBinDir.trim());
99937
- const homeDir = input.homeDir ?? homedir4();
100395
+ const homeDir = input.homeDir ?? homedir5();
99938
100396
  const defaultCodexHome = resolve12(homeDir, ".codex");
99939
100397
  const resolvedCodexHome = resolve12(input.codexHome);
99940
100398
  if (resolvedCodexHome !== defaultCodexHome)
@@ -99942,9 +100400,57 @@ function resolveCodexInstallerBinDir(input) {
99942
100400
  return resolve12(homeDir, ".local", "bin");
99943
100401
  }
99944
100402
 
99945
- // packages/omo-codex/src/install/codex-git-bash-hooks.ts
99946
- import { readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
100403
+ // packages/omo-codex/src/install/codex-installed-bin-dir.ts
100404
+ import { readFile as readFile20, readdir as readdir11, writeFile as writeFile11 } from "fs/promises";
99947
100405
  import { join as join49 } from "path";
100406
+ var INSTALLED_BIN_DIR_MANIFEST = ".installed-bin-dir.json";
100407
+ async function writeInstalledCodexBinDir(input) {
100408
+ await writeFile11(join49(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
100409
+ `);
100410
+ }
100411
+ async function readInstalledCodexBinDir(codexHome) {
100412
+ for (const manifestPath of await installedBinDirManifestPaths(codexHome)) {
100413
+ const binDir = await readBinDirFromManifest(manifestPath);
100414
+ if (binDir !== null)
100415
+ return binDir;
100416
+ }
100417
+ return null;
100418
+ }
100419
+ async function installedBinDirManifestPaths(codexHome) {
100420
+ const paths2 = [
100421
+ join49(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_BIN_DIR_MANIFEST)
100422
+ ];
100423
+ const versionRoot = join49(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
100424
+ const entries = await readdir11(versionRoot, { withFileTypes: true }).catch(() => null);
100425
+ if (entries !== null) {
100426
+ for (const entry of entries) {
100427
+ if (entry.isDirectory())
100428
+ paths2.push(join49(versionRoot, entry.name, INSTALLED_BIN_DIR_MANIFEST));
100429
+ }
100430
+ }
100431
+ return paths2;
100432
+ }
100433
+ async function readBinDirFromManifest(manifestPath) {
100434
+ const raw = await readFile20(manifestPath, "utf8").catch(() => null);
100435
+ if (raw === null)
100436
+ return null;
100437
+ let parsed;
100438
+ try {
100439
+ parsed = JSON.parse(raw);
100440
+ } catch {
100441
+ return null;
100442
+ }
100443
+ if (!isPlainRecord4(parsed))
100444
+ return null;
100445
+ const binDir = parsed.binDir;
100446
+ if (typeof binDir !== "string" || binDir.trim().length === 0)
100447
+ return null;
100448
+ return binDir.trim();
100449
+ }
100450
+
100451
+ // packages/omo-codex/src/install/codex-git-bash-hooks.ts
100452
+ import { readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
100453
+ import { join as join50 } from "path";
99948
100454
  var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
99949
100455
  "./hooks/pre-tool-use-recommending-git-bash-mcp.json",
99950
100456
  "./hooks/post-compact-resetting-git-bash-mcp-reminder.json"
@@ -99952,22 +100458,22 @@ var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
99952
100458
  async function removeGitBashHooksOffWindows(input) {
99953
100459
  if (input.platform === "win32")
99954
100460
  return;
99955
- const manifestPath = join49(input.pluginRoot, ".codex-plugin", "plugin.json");
99956
- const parsed = JSON.parse(await readFile20(manifestPath, "utf8"));
100461
+ const manifestPath = join50(input.pluginRoot, ".codex-plugin", "plugin.json");
100462
+ const parsed = JSON.parse(await readFile21(manifestPath, "utf8"));
99957
100463
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.hooks))
99958
100464
  return;
99959
100465
  const hooks = parsed.hooks.filter((hook) => typeof hook !== "string" || !WINDOWS_ONLY_GIT_BASH_HOOKS.has(hook));
99960
100466
  if (hooks.length === parsed.hooks.length)
99961
100467
  return;
99962
- await writeFile11(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
100468
+ await writeFile12(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
99963
100469
  `);
99964
100470
  }
99965
100471
 
99966
100472
  // packages/omo-codex/src/install/omo-sot-migration.ts
99967
- import { join as join50 } from "path";
100473
+ import { join as join51 } from "path";
99968
100474
  async function seedAndMigrateOmoSot(input) {
99969
100475
  const commandEnv = { ...input.env };
99970
- const scriptPath = join50(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
100476
+ const scriptPath = join51(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
99971
100477
  try {
99972
100478
  await input.runCommand(process.execPath, [scriptPath, "--seed"], {
99973
100479
  cwd: input.repoRoot,
@@ -99982,7 +100488,7 @@ async function seedAndMigrateOmoSot(input) {
99982
100488
 
99983
100489
  // packages/omo-codex/src/install/install-ast-grep-sg.ts
99984
100490
  init_src2();
99985
- import { join as join51 } from "path";
100491
+ import { join as join52 } from "path";
99986
100492
  function describeResult(result) {
99987
100493
  if (result.kind === "succeeded")
99988
100494
  return null;
@@ -99996,7 +100502,7 @@ async function installAstGrepForCodex(options) {
99996
100502
  return;
99997
100503
  const platform = options.platform ?? process.platform;
99998
100504
  const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
99999
- const skillDir = join51(plugin.path, "skills", "ast-grep");
100505
+ const skillDir = join52(plugin.path, "skills", "ast-grep");
100000
100506
  const installer = options.installer ?? runAstGrepSkillInstall;
100001
100507
  try {
100002
100508
  const result = await installer({ platform, skillDir, targetDir });
@@ -100030,7 +100536,7 @@ async function runCodexInstaller(options = {}) {
100030
100536
  const env3 = options.env ?? process.env;
100031
100537
  const platform = options.platform ?? process.platform;
100032
100538
  const repoRoot = resolve13(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env3 }));
100033
- const codexHome = resolve13(options.codexHome ?? env3.CODEX_HOME ?? join54(homedir5(), ".codex"));
100539
+ const codexHome = resolve13(options.codexHome ?? env3.CODEX_HOME ?? join55(homedir6(), ".codex"));
100034
100540
  const projectDirectory = resolve13(options.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd());
100035
100541
  const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env3 });
100036
100542
  const runCommand = options.runCommand ?? defaultRunCommand;
@@ -100047,9 +100553,9 @@ async function runCodexInstaller(options = {}) {
100047
100553
  if (!gitBashResolution.found) {
100048
100554
  throw new Error(gitBashResolution.installHint);
100049
100555
  }
100050
- const codexPackageRoot = join54(repoRoot, "packages", "omo-codex");
100556
+ const codexPackageRoot = join55(repoRoot, "packages", "omo-codex");
100051
100557
  const marketplace = await readMarketplace(repoRoot, {
100052
- marketplacePath: join54(codexPackageRoot, "marketplace.json")
100558
+ marketplacePath: join55(codexPackageRoot, "marketplace.json")
100053
100559
  });
100054
100560
  const distributionManifest = await readDistributionManifest(repoRoot);
100055
100561
  const installed = [];
@@ -100083,6 +100589,7 @@ async function runCodexInstaller(options = {}) {
100083
100589
  if (marketplace.name === "sisyphuslabs" && plugin.name === "omo") {
100084
100590
  await stampLazyCodexPluginVersion({ pluginRoot: plugin.path, version: version3 });
100085
100591
  await writeLazyCodexInstallSnapshot({ pluginRoot: plugin.path, distributionManifest });
100592
+ await writeInstalledCodexBinDir({ pluginRoot: plugin.path, binDir });
100086
100593
  await removeGitBashHooksOffWindows({ platform, pluginRoot: plugin.path });
100087
100594
  }
100088
100595
  const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path, platform });
@@ -100094,7 +100601,7 @@ async function runCodexInstaller(options = {}) {
100094
100601
  if (runtimeLink !== null)
100095
100602
  log4(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
100096
100603
  else
100097
- log4(`Warning: skipped the omo runtime wrapper because ${join54(repoRoot, "dist", "cli", "index.js")} is missing; omo ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
100604
+ log4(`Warning: skipped the omo-agent-toolkit runtime wrapper because ${join55(repoRoot, "dist", "cli", "index.js")} is missing; omo-agent-toolkit ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
100098
100605
  }
100099
100606
  pluginSources.push({ name: entry.name, sourcePath });
100100
100607
  installed.push(plugin);
@@ -100157,13 +100664,13 @@ async function runCodexInstaller(options = {}) {
100157
100664
  continue;
100158
100665
  log4(`Warning: deferred legacy Codex LSP daemon cleanup for v${cleanup.version}: ${cleanup.reason}`);
100159
100666
  }
100160
- const marketplaceRoot = join54(codexHome, "plugins", "cache", marketplace.name);
100667
+ const marketplaceRoot = join55(codexHome, "plugins", "cache", marketplace.name);
100161
100668
  await writeCachedMarketplaceManifest({
100162
100669
  marketplaceName: marketplace.name,
100163
100670
  marketplaceRoot,
100164
100671
  plugins: installed
100165
100672
  });
100166
- const configPath = join54(codexHome, "config.toml");
100673
+ const configPath = join55(codexHome, "config.toml");
100167
100674
  await updateCodexConfig({
100168
100675
  configPath,
100169
100676
  repoRoot: codexPackageRoot,
@@ -100224,7 +100731,7 @@ function findRepoRootFromImporter(importerDir) {
100224
100731
  for (let depth = 0;depth <= 7; depth += 1) {
100225
100732
  if (isRepoRootWithCodexPlugin(current))
100226
100733
  return current;
100227
- for (const wrapperPackageRoot of [join54(current, "node_modules", "oh-my-openagent"), join54(current, "oh-my-openagent")]) {
100734
+ for (const wrapperPackageRoot of [join55(current, "node_modules", "oh-my-openagent"), join55(current, "oh-my-openagent")]) {
100228
100735
  if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
100229
100736
  return wrapperPackageRoot;
100230
100737
  }
@@ -100242,7 +100749,7 @@ function findRepoRoot(input) {
100242
100749
  return findRepoRootFromImporter(input.importerDir);
100243
100750
  }
100244
100751
  function isRepoRootWithCodexPlugin(repoRoot) {
100245
- return existsSync28(join54(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
100752
+ return existsSync28(join55(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
100246
100753
  }
100247
100754
  function codexMarketplaceSource(marketplaceRoot) {
100248
100755
  return { sourceType: "local", source: marketplaceRoot };
@@ -100251,7 +100758,7 @@ function codexMarketplaceSource(marketplaceRoot) {
100251
100758
  init_bun_which_shim();
100252
100759
  import { execFile as execFile3 } from "child_process";
100253
100760
  import { existsSync as existsSync29 } from "fs";
100254
- import { homedir as homedir6 } from "os";
100761
+ import { homedir as homedir7 } from "os";
100255
100762
  import { posix as posix8, win32 as win324 } from "path";
100256
100763
  var CODEX_PATH_CHECK_LABEL = "codex (PATH)";
100257
100764
  var WINDOWS_START_APPS_ARGS = [
@@ -100262,7 +100769,7 @@ var WINDOWS_START_APPS_ARGS = [
100262
100769
  async function detectCodexInstallation(input = {}) {
100263
100770
  const platform = input.platform ?? process.platform;
100264
100771
  const env3 = input.env ?? process.env;
100265
- const homeDir = input.homeDir ?? homedir6();
100772
+ const homeDir = input.homeDir ?? homedir7();
100266
100773
  const exists6 = input.exists ?? existsSync29;
100267
100774
  const which2 = input.which ?? bunWhich;
100268
100775
  const checkedPaths = [CODEX_PATH_CHECK_LABEL];
@@ -100305,10 +100812,10 @@ function detectMacCodexInstallation(input) {
100305
100812
  return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop for macOS.");
100306
100813
  }
100307
100814
  async function detectWindowsCodexInstallation(input) {
100308
- for (const candidate of windowsCodexCliPaths(input.env)) {
100309
- input.checkedPaths.push(candidate);
100310
- if (input.exists(candidate))
100311
- return { found: true, source: "windows-standard-cli", path: candidate };
100815
+ for (const candidate2 of windowsCodexCliPaths(input.env)) {
100816
+ input.checkedPaths.push(candidate2);
100817
+ if (input.exists(candidate2))
100818
+ return { found: true, source: "windows-standard-cli", path: candidate2 };
100312
100819
  }
100313
100820
  input.checkedPaths.push("Windows Start Apps: Codex");
100314
100821
  const appId = await findWindowsCodexStartApp(input.runCommand);
@@ -100377,13 +100884,81 @@ function defaultRunCommand2(command, args) {
100377
100884
  });
100378
100885
  }
100379
100886
  // packages/omo-codex/src/install/codex-cleanup.ts
100380
- import { lstat as lstat13, readFile as readFile22, readdir as readdir11, rm as rm11, rmdir } from "fs/promises";
100381
- import { homedir as homedir7 } from "os";
100382
- import { isAbsolute as isAbsolute9, join as join56, relative as relative6, resolve as resolve15 } from "path";
100887
+ import { lstat as lstat14, readFile as readFile24, readdir as readdir13, rm as rm12, rmdir } from "fs/promises";
100888
+ import { homedir as homedir8 } from "os";
100889
+ import { isAbsolute as isAbsolute10, join as join58, relative as relative6, resolve as resolve16 } from "path";
100890
+
100891
+ // packages/omo-codex/src/install/codex-cleanup-bins.ts
100892
+ import { lstat as lstat12, readFile as readFile22, readdir as readdir12, readlink as readlink6, rm as rm11 } from "fs/promises";
100893
+ import { dirname as dirname18, isAbsolute as isAbsolute8, join as join56, resolve as resolve14 } from "path";
100894
+ var ROOT_RUNTIME_BIN_NAME = "omo";
100895
+ var MANAGED_CODEX_BIN_NAMES = new Set([
100896
+ ROOT_RUNTIME_BIN_NAME,
100897
+ "omo-codegraph",
100898
+ "omo-comment-checker",
100899
+ "omo-git-bash-hook",
100900
+ "omo-lsp",
100901
+ "omo-rules",
100902
+ "omo-start-work-continuation",
100903
+ "omo-telemetry",
100904
+ "omo-ultrawork",
100905
+ "omo-ulw-loop",
100906
+ "lazycodex-executor-verify",
100907
+ "ulw",
100908
+ "ulw-loop",
100909
+ ...LEGACY_CODEX_COMPONENT_BIN_NAMES
100910
+ ]);
100911
+ async function removeManagedCodexBins(binDir, platform) {
100912
+ const entries = await readdir12(binDir, { withFileTypes: true }).catch((error51) => {
100913
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
100914
+ return null;
100915
+ throw error51;
100916
+ });
100917
+ if (entries === null)
100918
+ return [];
100919
+ const removed2 = [];
100920
+ for (const entry of entries) {
100921
+ const binName = managedBinNameForEntry2(entry.name, platform);
100922
+ if (binName === null || !MANAGED_CODEX_BIN_NAMES.has(binName))
100923
+ continue;
100924
+ const linkPath = join56(binDir, entry.name);
100925
+ if (await isManagedCodexBin(linkPath, platform, binName)) {
100926
+ await rm11(linkPath, { force: true });
100927
+ removed2.push(linkPath);
100928
+ }
100929
+ }
100930
+ return removed2;
100931
+ }
100932
+ function managedBinNameForEntry2(entryName, platform) {
100933
+ if (platform !== "win32")
100934
+ return entryName;
100935
+ const normalizedEntryName = entryName.toLowerCase();
100936
+ return normalizedEntryName.endsWith(".cmd") ? normalizedEntryName.slice(0, -".cmd".length) : null;
100937
+ }
100938
+ async function isManagedCodexBin(linkPath, platform, binName) {
100939
+ const entryStat = await lstat12(linkPath).catch((error51) => {
100940
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
100941
+ return null;
100942
+ throw error51;
100943
+ });
100944
+ if (entryStat === null)
100945
+ return false;
100946
+ if (entryStat.isSymbolicLink()) {
100947
+ if (platform === "win32")
100948
+ return false;
100949
+ const linkTarget = await readlink6(linkPath);
100950
+ const target = isAbsolute8(linkTarget) ? linkTarget : resolve14(dirname18(linkPath), linkTarget);
100951
+ return isManagedComponentBinTarget(target) || isLegacyCodexBinTarget(binName, target);
100952
+ }
100953
+ if (!entryStat.isFile())
100954
+ return false;
100955
+ const content = await readFile22(linkPath, "utf8");
100956
+ return content.includes(RUNTIME_WRAPPER_MARKER) || content.includes(COMMAND_SHIM_MARKER);
100957
+ }
100383
100958
 
100384
100959
  // packages/omo-codex/src/install/codex-cleanup-config.ts
100385
- import { lstat as lstat12, mkdir as mkdir8, readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
100386
- import { dirname as dirname18 } from "path";
100960
+ import { lstat as lstat13, mkdir as mkdir8, readFile as readFile23, writeFile as writeFile13 } from "fs/promises";
100961
+ import { dirname as dirname19 } from "path";
100387
100962
  var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
100388
100963
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE2 = ["codex-ultrawork-reviewer"];
100389
100964
  var CURRENT_MANAGED_CODEX_AGENT_NAMES2 = [
@@ -100415,14 +100990,14 @@ function cleanupCodexLightConfigText(config3) {
100415
100990
  async function cleanupCodexConfig(configPath, now) {
100416
100991
  if (!await configExists(configPath))
100417
100992
  return { changed: false };
100418
- const original = await readFile21(configPath, "utf8");
100993
+ const original = await readFile23(configPath, "utf8");
100419
100994
  const next = cleanupCodexLightConfigText(original);
100420
100995
  if (next === original)
100421
100996
  return { changed: false };
100422
100997
  const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
100423
- await mkdir8(dirname18(configPath), { recursive: true });
100424
- await writeFile12(backupPath, original);
100425
- await writeFile12(configPath, `${next.trimEnd()}
100998
+ await mkdir8(dirname19(configPath), { recursive: true });
100999
+ await writeFile13(backupPath, original);
101000
+ await writeFile13(configPath, `${next.trimEnd()}
100426
101001
  `);
100427
101002
  return { changed: true, backupPath };
100428
101003
  }
@@ -100484,7 +101059,7 @@ function formatBackupTimestamp2(date5) {
100484
101059
  }
100485
101060
  async function configExists(path6) {
100486
101061
  try {
100487
- await lstat12(path6);
101062
+ await lstat13(path6);
100488
101063
  return true;
100489
101064
  } catch (error51) {
100490
101065
  if (nodeErrorCode5(error51) === "ENOENT")
@@ -100499,24 +101074,28 @@ function nodeErrorCode5(error51) {
100499
101074
  }
100500
101075
 
100501
101076
  // packages/omo-codex/src/install/codex-cleanup-safety.ts
100502
- import { dirname as dirname19, isAbsolute as isAbsolute8, join as join55, relative as relative5, resolve as resolve14 } from "path";
101077
+ import { dirname as dirname20, isAbsolute as isAbsolute9, join as join57, relative as relative5, resolve as resolve15 } from "path";
101078
+ function codexHomeResolvesToFilesystemRoot(codexHome) {
101079
+ const resolved = resolve15(codexHome);
101080
+ return dirname20(resolved) === resolved;
101081
+ }
100503
101082
  function validateManagedCleanupTarget(input) {
100504
- if (!isAbsolute8(input.path))
101083
+ if (!isAbsolute9(input.path))
100505
101084
  return skipped(input.path, "outside managed Codex cleanup scope");
100506
- const codexHome = resolve14(input.codexHome);
100507
- if (dirname19(codexHome) === codexHome)
101085
+ const codexHome = resolve15(input.codexHome);
101086
+ if (codexHomeResolvesToFilesystemRoot(codexHome))
100508
101087
  return skipped(input.path, "Codex home resolves to a filesystem root");
100509
- const target = resolve14(input.path);
101088
+ const target = resolve15(input.path);
100510
101089
  if (!isWithinDirectory(codexHome, target))
100511
101090
  return skipped(input.path, "outside managed Codex cleanup scope");
100512
101091
  if (target === codexHome)
100513
101092
  return skipped(input.path, "outside managed Codex cleanup scope");
100514
101093
  const exactManagedRoots = new Set([
100515
- resolve14(join55(codexHome, "plugins", "cache", "sisyphuslabs")),
100516
- resolve14(join55(codexHome, ".tmp", "marketplaces", "sisyphuslabs")),
100517
- resolve14(join55(codexHome, "runtime", "ast-grep")),
100518
- resolve14(join55(codexHome, "runtime", "node")),
100519
- resolve14(join55(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap"))
101094
+ resolve15(join57(codexHome, "plugins", "cache", "sisyphuslabs")),
101095
+ resolve15(join57(codexHome, ".tmp", "marketplaces", "sisyphuslabs")),
101096
+ resolve15(join57(codexHome, "runtime", "ast-grep")),
101097
+ resolve15(join57(codexHome, "runtime", "node")),
101098
+ resolve15(join57(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap"))
100520
101099
  ]);
100521
101100
  if (exactManagedRoots.has(target))
100522
101101
  return null;
@@ -100526,7 +101105,7 @@ function validateManagedCleanupTarget(input) {
100526
101105
  }
100527
101106
  function isWithinDirectory(parent, child) {
100528
101107
  const relativePath = relative5(parent, child);
100529
- return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute8(relativePath);
101108
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute9(relativePath);
100530
101109
  }
100531
101110
  function isManagedBootstrapDriftPath(codexHome, target) {
100532
101111
  const relativePath = relative5(codexHome, target);
@@ -100546,8 +101125,9 @@ function skipped(path6, reason) {
100546
101125
  var INSTALLED_AGENTS_MANIFEST = ".installed-agents.json";
100547
101126
  async function cleanupCodexLight(input = {}) {
100548
101127
  const env3 = input.env ?? process.env;
100549
- const codexHome = resolve15(input.codexHome ?? env3.CODEX_HOME ?? join56(homedir7(), ".codex"));
100550
- const configPath = join56(codexHome, "config.toml");
101128
+ const codexHome = resolve16(input.codexHome ?? env3.CODEX_HOME ?? join58(homedir8(), ".codex"));
101129
+ const configPath = join58(codexHome, "config.toml");
101130
+ const installedBinDir = await readInstalledCodexBinDir(codexHome);
100551
101131
  const agentPaths = await collectInstalledAgentPaths(codexHome, configPath);
100552
101132
  const configCleanup = await cleanupCodexConfig(configPath, input.now);
100553
101133
  const agentCleanup = await removeManifestListedAgentLinks(codexHome, agentPaths);
@@ -100563,6 +101143,12 @@ async function cleanupCodexLight(input = {}) {
100563
101143
  }
100564
101144
  }
100565
101145
  await pruneEmptyRuntimeDirBestEffort(codexHome);
101146
+ const binDir = resolveCodexInstallerBinDir({
101147
+ binDir: firstConfiguredPath(input.binDir, env3.CODEX_LOCAL_BIN_DIR, installedBinDir),
101148
+ codexHome,
101149
+ env: env3
101150
+ });
101151
+ const removedBinLinks = codexHomeResolvesToFilesystemRoot(codexHome) ? [] : await removeManagedCodexBins(binDir, input.platform ?? process.platform);
100566
101152
  const projectDirectory = input.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd();
100567
101153
  const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
100568
101154
  startDirectory: projectDirectory,
@@ -100581,36 +101167,44 @@ async function cleanupCodexLight(input = {}) {
100581
101167
  skippedPaths,
100582
101168
  removedAgentLinks: agentCleanup.removed,
100583
101169
  skippedAgentLinks: agentCleanup.skipped,
101170
+ removedBinLinks,
100584
101171
  projectCleanup
100585
101172
  };
100586
101173
  }
101174
+ function firstConfiguredPath(...values) {
101175
+ for (const value of values) {
101176
+ if (typeof value === "string" && value.trim().length > 0)
101177
+ return value;
101178
+ }
101179
+ return;
101180
+ }
100587
101181
  function managedGlobalStatePaths(codexHome) {
100588
101182
  return [
100589
- join56(codexHome, "plugins", "cache", "sisyphuslabs"),
100590
- join56(codexHome, ".tmp", "marketplaces", "sisyphuslabs"),
100591
- join56(codexHome, "runtime", "ast-grep"),
100592
- join56(codexHome, "runtime", "node"),
100593
- join56(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap")
101183
+ join58(codexHome, "plugins", "cache", "sisyphuslabs"),
101184
+ join58(codexHome, ".tmp", "marketplaces", "sisyphuslabs"),
101185
+ join58(codexHome, "runtime", "ast-grep"),
101186
+ join58(codexHome, "runtime", "node"),
101187
+ join58(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap")
100594
101188
  ];
100595
101189
  }
100596
101190
  var BOOTSTRAP_DATA_GLOB_MAX_DEPTH = 5;
100597
101191
  async function collectBootstrapDataDirsByGlob(codexHome) {
100598
101192
  const results = [];
100599
- await walkForManagedBootstrapDirs(join56(codexHome, "plugins"), 0, results);
101193
+ await walkForManagedBootstrapDirs(join58(codexHome, "plugins"), 0, results);
100600
101194
  return results;
100601
101195
  }
100602
101196
  async function walkForManagedBootstrapDirs(directory, depth, results) {
100603
101197
  if (depth > BOOTSTRAP_DATA_GLOB_MAX_DEPTH)
100604
101198
  return;
100605
- const entries = await readdir11(directory, { withFileTypes: true }).catch(() => null);
101199
+ const entries = await readdir13(directory, { withFileTypes: true }).catch(() => null);
100606
101200
  if (entries === null)
100607
101201
  return;
100608
101202
  for (const entry of entries) {
100609
101203
  if (!entry.isDirectory())
100610
101204
  continue;
100611
- const childPath = join56(directory, entry.name);
101205
+ const childPath = join58(directory, entry.name);
100612
101206
  if (isManagedBootstrapOwnerName(entry.name)) {
100613
- const bootstrapDir = join56(childPath, "bootstrap");
101207
+ const bootstrapDir = join58(childPath, "bootstrap");
100614
101208
  if (await exists6(bootstrapDir))
100615
101209
  results.push(bootstrapDir);
100616
101210
  continue;
@@ -100634,9 +101228,9 @@ async function removeManagedPathBestEffort(path6, seams) {
100634
101228
  }
100635
101229
  async function attemptRemove(path6) {
100636
101230
  try {
100637
- if (await lstat13(path6).catch(() => null) === null)
101231
+ if (await lstat14(path6).catch(() => null) === null)
100638
101232
  return false;
100639
- await rm11(path6, { recursive: true, force: true });
101233
+ await rm12(path6, { recursive: true, force: true });
100640
101234
  return true;
100641
101235
  } catch {
100642
101236
  return false;
@@ -100644,7 +101238,7 @@ async function attemptRemove(path6) {
100644
101238
  }
100645
101239
  async function pruneEmptyRuntimeDirBestEffort(codexHome) {
100646
101240
  try {
100647
- await rmdir(join56(codexHome, "runtime"));
101241
+ await rmdir(join58(codexHome, "runtime"));
100648
101242
  } catch (error51) {
100649
101243
  if (isExpectedRuntimePruneFailure(error51))
100650
101244
  return;
@@ -100656,14 +101250,14 @@ function isExpectedRuntimePruneFailure(error51) {
100656
101250
  }
100657
101251
  async function collectInstalledAgentPaths(codexHome, configPath) {
100658
101252
  const manifestPaths = [
100659
- join56(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
101253
+ join58(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
100660
101254
  ];
100661
- const versionRoot = join56(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
101255
+ const versionRoot = join58(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
100662
101256
  if (await exists6(versionRoot)) {
100663
- const entries = await readdir11(versionRoot, { withFileTypes: true });
101257
+ const entries = await readdir13(versionRoot, { withFileTypes: true });
100664
101258
  for (const entry of entries) {
100665
101259
  if (entry.isDirectory())
100666
- manifestPaths.push(join56(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
101260
+ manifestPaths.push(join58(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
100667
101261
  }
100668
101262
  }
100669
101263
  const paths2 = new Set;
@@ -100680,19 +101274,19 @@ async function collectInstalledAgentPaths(codexHome, configPath) {
100680
101274
  async function readManagedAgentPathsFromConfig(codexHome, configPath) {
100681
101275
  if (!await exists6(configPath))
100682
101276
  return [];
100683
- const config3 = await readFile22(configPath, "utf8");
100684
- return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config3.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join56(codexHome, "agents", `${agentName}.toml`));
101277
+ const config3 = await readFile24(configPath, "utf8");
101278
+ return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config3.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join58(codexHome, "agents", `${agentName}.toml`));
100685
101279
  }
100686
101280
  async function readInstalledAgentManifest(manifestPath) {
100687
101281
  if (!await exists6(manifestPath))
100688
101282
  return [];
100689
- const parsed = JSON.parse(await readFile22(manifestPath, "utf8"));
101283
+ const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
100690
101284
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.agents))
100691
101285
  return [];
100692
101286
  return parsed.agents.filter((path6) => typeof path6 === "string");
100693
101287
  }
100694
101288
  async function removeManifestListedAgentLinks(codexHome, paths2) {
100695
- const agentsDir = join56(codexHome, "agents");
101289
+ const agentsDir = join58(codexHome, "agents");
100696
101290
  const removed2 = [];
100697
101291
  const skipped2 = [];
100698
101292
  for (const path6 of paths2) {
@@ -100707,16 +101301,16 @@ async function removeManifestListedAgentLinks(codexHome, paths2) {
100707
101301
  skipped2.push(path6);
100708
101302
  continue;
100709
101303
  }
100710
- await rm11(path6, { force: true });
101304
+ await rm12(path6, { force: true });
100711
101305
  removed2.push(path6);
100712
101306
  }
100713
101307
  return { removed: removed2, skipped: skipped2 };
100714
101308
  }
100715
101309
  function isSafeManagedAgentPath(agentsDir, path6) {
100716
- if (!isAbsolute9(path6))
101310
+ if (!isAbsolute10(path6))
100717
101311
  return false;
100718
101312
  const relativePath = relative6(agentsDir, path6);
100719
- if (relativePath === "" || relativePath.startsWith("..") || isAbsolute9(relativePath))
101313
+ if (relativePath === "" || relativePath.startsWith("..") || isAbsolute10(relativePath))
100720
101314
  return false;
100721
101315
  const fileName = relativePath.split(/[\\/]/).pop();
100722
101316
  if (fileName === undefined)
@@ -100728,7 +101322,7 @@ async function exists6(path6) {
100728
101322
  }
100729
101323
  async function maybeLstat2(path6) {
100730
101324
  try {
100731
- return await lstat13(path6);
101325
+ return await lstat14(path6);
100732
101326
  } catch (error51) {
100733
101327
  if (nodeErrorCode6(error51) === "ENOENT")
100734
101328
  return null;
@@ -100744,52 +101338,162 @@ function nodeErrorCode6(error51) {
100744
101338
  var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
100745
101339
  // packages/omo-senpi/src/install/install-senpi.ts
100746
101340
  import { execFile as execFile4 } from "child_process";
100747
- import { constants as constants7, existsSync as existsSync30 } from "fs";
100748
- import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile23, rename as rename5, writeFile as writeFile13 } from "fs/promises";
100749
- import { homedir as homedir8 } from "os";
100750
- import { dirname as dirname20, join as join57, resolve as resolve16 } from "path";
101341
+ import { createHash as createHash5 } from "crypto";
101342
+ import { constants as constants8, existsSync as existsSync30 } from "fs";
101343
+ import { access as access2, readFile as readFile26, stat as stat6 } from "fs/promises";
101344
+ import { homedir as homedir9 } from "os";
101345
+ import { dirname as dirname22, join as join60, resolve as resolve18 } from "path";
100751
101346
  import { fileURLToPath } from "url";
100752
101347
  import { promisify as promisify2 } from "util";
101348
+
101349
+ // packages/omo-senpi/src/install/senpi-settings.ts
101350
+ import { constants as constants7 } from "fs";
101351
+ import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile25, rename as rename5, writeFile as writeFile14 } from "fs/promises";
101352
+ import { dirname as dirname21, join as join59, resolve as resolve17 } from "path";
101353
+ var OMO_SENPI_PACKAGE_NAME = "@code-yeongyu/omo-senpi";
101354
+ var LEGACY_BUILTIN_SHADOW_PACKAGES = [
101355
+ join59("packages", "pi-goal"),
101356
+ join59("packages", "pi-webfetch")
101357
+ ];
101358
+ async function readSettings(settingsPath) {
101359
+ let raw;
101360
+ try {
101361
+ raw = await readFile25(settingsPath, "utf8");
101362
+ } catch (error51) {
101363
+ if (isErrno(error51, "ENOENT"))
101364
+ return {};
101365
+ throw error51;
101366
+ }
101367
+ const parsed = JSON.parse(raw);
101368
+ if (!isRecord10(parsed))
101369
+ throw new Error(`${settingsPath} must contain a JSON object`);
101370
+ return parsed;
101371
+ }
101372
+ function readPackages(settings) {
101373
+ const packages = settings.packages;
101374
+ if (packages === undefined)
101375
+ return [];
101376
+ if (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string")) {
101377
+ throw new Error("Senpi settings packages must be an array of strings");
101378
+ }
101379
+ return packages;
101380
+ }
101381
+ function dedupePackages(packages) {
101382
+ return [...new Set(packages)];
101383
+ }
101384
+ function removeLegacyBuiltinShadows(packages, repoRoot, agentDir) {
101385
+ const shadowPaths = new Set(LEGACY_BUILTIN_SHADOW_PACKAGES.map((path6) => resolve17(repoRoot, path6)));
101386
+ return packages.filter((entry) => !shadowPaths.has(resolve17(agentDir, entry)));
101387
+ }
101388
+ async function removeSupersededOmoPackages(packages, currentPluginPath, agentDir) {
101389
+ const currentPath = resolve17(currentPluginPath);
101390
+ const entries = await Promise.all(packages.map(async (entry) => {
101391
+ const packagePath = resolve17(agentDir, entry);
101392
+ if (packagePath === currentPath)
101393
+ return currentPath;
101394
+ return await readPackageName(packagePath) === OMO_SENPI_PACKAGE_NAME ? undefined : entry;
101395
+ }));
101396
+ return entries.filter((entry) => entry !== undefined);
101397
+ }
101398
+ async function writeSettingsAtomically(settingsPath, settings) {
101399
+ await mkdir9(dirname21(settingsPath), { recursive: true });
101400
+ const backupPath = await nextBackupPath(settingsPath);
101401
+ if (await fileExists(settingsPath)) {
101402
+ await copyFile3(settingsPath, backupPath);
101403
+ } else {
101404
+ await writeFile14(backupPath, `{}
101405
+ `, "utf8");
101406
+ }
101407
+ const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
101408
+ await writeFile14(tempPath, `${JSON.stringify(settings, null, 2)}
101409
+ `, "utf8");
101410
+ await rename5(tempPath, settingsPath);
101411
+ return backupPath;
101412
+ }
101413
+ async function nextBackupPath(settingsPath) {
101414
+ for (let index = 0;index < 1000; index += 1) {
101415
+ const suffix = index === 0 ? "" : `-${index}`;
101416
+ const candidate2 = `${settingsPath}.${timestampForBackup()}${suffix}.backup`;
101417
+ if (!await fileExists(candidate2))
101418
+ return candidate2;
101419
+ }
101420
+ throw new Error(`Unable to allocate backup path for ${settingsPath}`);
101421
+ }
101422
+ function timestampForBackup() {
101423
+ return new Date().toISOString().replace(/[-:.]/g, "");
101424
+ }
101425
+ function isRecord10(value) {
101426
+ return typeof value === "object" && value !== null && !Array.isArray(value);
101427
+ }
101428
+ async function readPackageName(packagePath) {
101429
+ let raw;
101430
+ try {
101431
+ raw = await readFile25(join59(packagePath, "package.json"), "utf8");
101432
+ } catch (error51) {
101433
+ if (isErrno(error51, "ENOENT") || isErrno(error51, "ENOTDIR"))
101434
+ return;
101435
+ throw error51;
101436
+ }
101437
+ const parsed = JSON.parse(raw);
101438
+ return isRecord10(parsed) && typeof parsed.name === "string" ? parsed.name : undefined;
101439
+ }
101440
+ async function fileExists(path6) {
101441
+ try {
101442
+ await access(path6, constants7.F_OK);
101443
+ return true;
101444
+ } catch (error51) {
101445
+ if (isErrno(error51, "ENOENT"))
101446
+ return false;
101447
+ throw error51;
101448
+ }
101449
+ }
101450
+ function isErrno(error51, code) {
101451
+ return error51 instanceof Error && "code" in error51 && error51.code === code;
101452
+ }
101453
+
101454
+ // packages/omo-senpi/src/install/install-senpi.ts
100753
101455
  var execFileAsync2 = promisify2(execFile4);
100754
101456
  var REQUIRED_PLUGIN_ARTIFACTS = [
100755
- join57("extensions", "omo.js"),
100756
- join57("skills", "ast-grep", "SKILL.md"),
100757
- join57("skills", "coding-agent-sessions", "SKILL.md"),
100758
- join57("skills", "debugging", "SKILL.md"),
100759
- join57("skills", "frontend", "SKILL.md"),
100760
- join57("skills", "git-master", "SKILL.md"),
100761
- join57("skills", "init-deep", "SKILL.md"),
100762
- join57("skills", "lsp-setup", "SKILL.md"),
100763
- join57("skills", "programming", "SKILL.md"),
100764
- join57("skills", "refactor", "SKILL.md"),
100765
- join57("skills", "remove-ai-slops", "SKILL.md"),
100766
- join57("skills", "review-work", "SKILL.md"),
100767
- join57("skills", "start-work", "SKILL.md"),
100768
- join57("skills", "ultimate-browsing", "SKILL.md"),
100769
- join57("skills", "ultrawork", "SKILL.md"),
100770
- join57("skills", "ulw-loop", "SKILL.md"),
100771
- join57("skills", "ulw-plan", "SKILL.md"),
100772
- join57("skills", "ulw-research", "SKILL.md"),
100773
- join57("skills", "visual-qa", "SKILL.md"),
100774
- join57("runtime", "lsp-daemon", "dist", "cli.js"),
100775
- join57("runtime", "lsp-daemon", "dist", "index.js"),
100776
- join57("runtime", "lsp-daemon", "dist", "index.d.ts"),
100777
- join57("runtime", "lsp-daemon", "dist", "daemon-client.js"),
100778
- join57("runtime", "lsp-daemon", "dist", "daemon-client.d.ts"),
100779
- join57("runtime", "lsp-daemon", "dist", "package.json"),
100780
- join57("runtime", "lsp-daemon", "dist", ".omo-runtime-manifest.json"),
100781
- join57("scripts", "install.mjs")
100782
- ];
100783
- var LEGACY_BUILTIN_SHADOW_PACKAGES = [
100784
- join57("packages", "pi-goal"),
100785
- join57("packages", "pi-webfetch")
101457
+ join60("extensions", "omo.js"),
101458
+ join60("extensions", "reflection-persona.md"),
101459
+ join60("skills", "ast-grep", "SKILL.md"),
101460
+ join60("skills", "coding-agent-sessions", "SKILL.md"),
101461
+ join60("skills", "debugging", "SKILL.md"),
101462
+ join60("skills", "frontend", "SKILL.md"),
101463
+ join60("skills", "git-master", "SKILL.md"),
101464
+ join60("skills", "init-deep", "SKILL.md"),
101465
+ join60("skills", "lsp-setup", "SKILL.md"),
101466
+ join60("skills", "programming", "SKILL.md"),
101467
+ join60("skills", "refactor", "SKILL.md"),
101468
+ join60("skills", "remove-ai-slops", "SKILL.md"),
101469
+ join60("skills", "review-work", "SKILL.md"),
101470
+ join60("skills", "start-work", "SKILL.md"),
101471
+ join60("skills", "ultimate-browsing", "SKILL.md"),
101472
+ join60("skills", "ultrawork", "SKILL.md"),
101473
+ join60("skills", "ulw-loop", "SKILL.md"),
101474
+ join60("skills", "ulw-plan", "SKILL.md"),
101475
+ join60("skills", "ulw-research", "SKILL.md"),
101476
+ join60("skills", "visual-qa", "SKILL.md"),
101477
+ join60("runtime", "ast-grep-mcp", "cli.js"),
101478
+ join60("runtime", "agent-toolkit", "cli.js"),
101479
+ join60("runtime", "agent-toolkit", "ulw-loop", "cli.js"),
101480
+ join60("runtime", "agent-toolkit", "omo-agent-toolkit"),
101481
+ join60("runtime", "agent-toolkit", "omo-agent-toolkit.cmd"),
101482
+ join60("runtime", "lsp-daemon", "dist", "cli.js"),
101483
+ join60("runtime", "lsp-daemon", "dist", "index.js"),
101484
+ join60("runtime", "lsp-daemon", "dist", "index.d.ts"),
101485
+ join60("runtime", "lsp-daemon", "dist", "daemon-client.js"),
101486
+ join60("runtime", "lsp-daemon", "dist", "daemon-client.d.ts"),
101487
+ join60("runtime", "lsp-daemon", "dist", "package.json"),
101488
+ join60("runtime", "lsp-daemon", "dist", ".omo-runtime-manifest.json"),
101489
+ join60("scripts", "install.mjs")
100786
101490
  ];
100787
101491
  async function runSenpiInstaller(options = {}) {
100788
101492
  const context = resolveInstallContext(options);
100789
101493
  await ensurePluginArtifacts(context);
100790
101494
  const settings = await readSettings(context.settingsPath);
100791
101495
  const before = JSON.stringify(settings);
100792
- const packages = removeLegacyBuiltinShadows(dedupePackages(readPackages(settings)), context.repoRoot, context.agentDir);
101496
+ const packages = dedupePackages(await removeSupersededOmoPackages(removeLegacyBuiltinShadows(dedupePackages(readPackages(settings)), context.repoRoot, context.agentDir), context.pluginPath, context.agentDir));
100793
101497
  if (!packages.includes(context.pluginPath))
100794
101498
  packages.push(context.pluginPath);
100795
101499
  settings.packages = packages;
@@ -100807,121 +101511,113 @@ async function runSenpiInstaller(options = {}) {
100807
101511
  function resolveInstallContext(options) {
100808
101512
  const env3 = options.env ?? process.env;
100809
101513
  const allowBuild = options.pluginPath === undefined;
100810
- const repoRoot = resolve16(options.repoRoot ?? (allowBuild ? findRepoRoot2(dirname20(fileURLToPath(import.meta.url))) : dirname20(resolve16(options.pluginPath))));
100811
- const agentDir = resolve16(options.agentDir ?? env3.SENPI_CODING_AGENT_DIR ?? join57(homedir8(), ".senpi", "agent"));
100812
- const pluginPath = resolve16(options.pluginPath ?? join57(repoRoot, "packages", "omo-senpi", "plugin"));
101514
+ const repoRoot = resolve18(options.repoRoot ?? (allowBuild ? findRepoRoot2(dirname22(fileURLToPath(import.meta.url))) : dirname22(resolve18(options.pluginPath))));
101515
+ const agentDir = resolve18(options.agentDir ?? env3.SENPI_CODING_AGENT_DIR ?? join60(homedir9(), ".senpi", "agent"));
101516
+ const pluginPath = resolve18(options.pluginPath ?? join60(repoRoot, "packages", "omo-senpi", "plugin"));
100813
101517
  return {
100814
101518
  env: env3,
100815
101519
  repoRoot,
100816
101520
  agentDir,
100817
- settingsPath: join57(agentDir, "settings.json"),
101521
+ settingsPath: join60(agentDir, "settings.json"),
100818
101522
  pluginPath,
101523
+ platform: options.platform ?? process.platform,
100819
101524
  allowBuild,
100820
101525
  runCommand: options.runCommand ?? defaultRunCommand3
100821
101526
  };
100822
101527
  }
100823
101528
  async function ensurePluginArtifacts(context) {
100824
- const missing = await hasMissingPluginArtifact(context.pluginPath);
100825
- if (!missing)
100826
- return;
100827
- if (!context.allowBuild) {
101529
+ if (context.allowBuild) {
101530
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
101531
+ await context.runCommand("node", [join60("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
101532
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
101533
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
101534
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
101535
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-ast-grep-mcp-runtime.mjs")], { cwd: context.repoRoot });
101536
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-agent-toolkit.mjs")], { cwd: context.repoRoot });
101537
+ }
101538
+ if (await hasMissingPluginArtifact(context.pluginPath)) {
100828
101539
  throw new Error(`Packed omo-senpi plugin is missing required runtime artifacts at ${context.pluginPath}`);
100829
101540
  }
100830
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
100831
- await context.runCommand("node", [join57("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
100832
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
100833
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
100834
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
101541
+ await verifyAstGrepRuntimeIntegrity(context.pluginPath, context.platform);
100835
101542
  }
100836
101543
  async function hasMissingPluginArtifact(pluginPath) {
100837
101544
  for (const artifact of REQUIRED_PLUGIN_ARTIFACTS) {
100838
- if (!await fileExists(join57(pluginPath, artifact)))
101545
+ if (!await fileExists2(join60(pluginPath, artifact)))
100839
101546
  return true;
100840
101547
  }
100841
101548
  return false;
100842
101549
  }
100843
- async function defaultRunCommand3(command, args, options) {
100844
- const result = await execFileAsync2(command, [...args], { cwd: options.cwd });
100845
- if (result.stderr.trim().length > 0)
100846
- process.stderr.write(result.stderr);
100847
- if (result.stdout.trim().length > 0)
100848
- process.stdout.write(result.stdout);
100849
- }
100850
- async function readSettings(settingsPath) {
100851
- let raw;
101550
+ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
101551
+ const runtimeEntry = join60(pluginPath, "runtime", "ast-grep-mcp", "cli.js");
101552
+ const manifestPath = join60(dirname22(runtimeEntry), "manifest.json");
101553
+ let runtimeStat;
100852
101554
  try {
100853
- raw = await readFile23(settingsPath, "utf8");
101555
+ runtimeStat = await stat6(runtimeEntry);
101556
+ if (!runtimeStat.isFile())
101557
+ throw new Error("runtime is not a file");
101558
+ await access2(runtimeEntry, constants8.R_OK | constants8.X_OK);
100854
101559
  } catch (error51) {
100855
- if (isErrno(error51, "ENOENT"))
100856
- return {};
100857
- throw error51;
101560
+ throw astGrepIntegrityError(runtimeEntry, `runtime is unreadable or non-executable: ${messageOf(error51)}`);
100858
101561
  }
100859
- const parsed = JSON.parse(raw);
100860
- if (!isPlainObject6(parsed))
100861
- throw new Error(`${settingsPath} must contain a JSON object`);
100862
- return parsed;
100863
- }
100864
- function readPackages(settings) {
100865
- const packages = settings.packages;
100866
- if (packages === undefined)
100867
- return [];
100868
- if (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string")) {
100869
- throw new Error("Senpi settings packages must be an array of strings");
101562
+ if (!await fileExists2(manifestPath)) {
101563
+ throw astGrepIntegrityError(runtimeEntry, `manifest is missing: ${manifestPath}`);
101564
+ }
101565
+ let manifest2;
101566
+ try {
101567
+ manifest2 = JSON.parse(await readFile26(manifestPath, "utf8"));
101568
+ } catch (error51) {
101569
+ throw astGrepIntegrityError(runtimeEntry, `manifest is unreadable or invalid JSON: ${messageOf(error51)}`);
101570
+ }
101571
+ if (!isAstGrepRuntimeManifest(manifest2)) {
101572
+ throw astGrepIntegrityError(runtimeEntry, `manifest is malformed: ${manifestPath}`);
101573
+ }
101574
+ let actualSha256;
101575
+ try {
101576
+ actualSha256 = createHash5("sha256").update(await readFile26(runtimeEntry)).digest("hex");
101577
+ } catch (error51) {
101578
+ throw astGrepIntegrityError(runtimeEntry, `runtime hash could not be computed: ${messageOf(error51)}`);
101579
+ }
101580
+ if (actualSha256 !== manifest2.sha256) {
101581
+ throw astGrepIntegrityError(runtimeEntry, `sha256 mismatch: manifest=${manifest2.sha256} actual=${actualSha256}`);
101582
+ }
101583
+ const actualMode = runtimeStat.mode & 511;
101584
+ if (platform !== "win32" && actualMode !== manifest2.mode) {
101585
+ throw astGrepIntegrityError(runtimeEntry, `mode mismatch: manifest=${manifest2.mode} actual=${actualMode}`);
100870
101586
  }
100871
- return packages;
100872
101587
  }
100873
- function dedupePackages(packages) {
100874
- return [...new Set(packages)];
101588
+ function isAstGrepRuntimeManifest(value) {
101589
+ if (!isRecord10(value))
101590
+ return false;
101591
+ return typeof value.sha256 === "string" && /^[a-f0-9]{64}$/.test(value.sha256) && typeof value.mode === "number" && Number.isInteger(value.mode) && typeof value.stagedAtUtc === "string" && !Number.isNaN(Date.parse(value.stagedAtUtc));
100875
101592
  }
100876
- function removeLegacyBuiltinShadows(packages, repoRoot, agentDir) {
100877
- const shadowPaths = new Set(LEGACY_BUILTIN_SHADOW_PACKAGES.map((path6) => resolve16(repoRoot, path6)));
100878
- return packages.filter((entry) => !shadowPaths.has(resolve16(agentDir, entry)));
101593
+ function astGrepIntegrityError(runtimeEntry, reason) {
101594
+ return new Error(`Packed omo-senpi plugin ast-grep MCP runtime integrity error at ${runtimeEntry}: ${reason}`);
100879
101595
  }
100880
- async function writeSettingsAtomically(settingsPath, settings) {
100881
- await mkdir9(dirname20(settingsPath), { recursive: true });
100882
- const backupPath = await nextBackupPath(settingsPath);
100883
- if (await fileExists(settingsPath)) {
100884
- await copyFile3(settingsPath, backupPath);
100885
- } else {
100886
- await writeFile13(backupPath, `{}
100887
- `, "utf8");
100888
- }
100889
- const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
100890
- await writeFile13(tempPath, `${JSON.stringify(settings, null, 2)}
100891
- `, "utf8");
100892
- await rename5(tempPath, settingsPath);
100893
- return backupPath;
100894
- }
100895
- async function nextBackupPath(settingsPath) {
100896
- for (let index = 0;index < 1000; index += 1) {
100897
- const suffix = index === 0 ? "" : `-${index}`;
100898
- const candidate = `${settingsPath}.${timestampForBackup()}${suffix}.backup`;
100899
- if (!await fileExists(candidate))
100900
- return candidate;
100901
- }
100902
- throw new Error(`Unable to allocate backup path for ${settingsPath}`);
101596
+ function messageOf(error51) {
101597
+ return error51 instanceof Error ? error51.message : String(error51);
100903
101598
  }
100904
- function timestampForBackup() {
100905
- return new Date().toISOString().replace(/[-:.]/g, "");
101599
+ async function defaultRunCommand3(command, args, options) {
101600
+ const result = await execFileAsync2(command, [...args], { cwd: options.cwd });
101601
+ if (result.stderr.trim().length > 0)
101602
+ process.stderr.write(result.stderr);
101603
+ if (result.stdout.trim().length > 0)
101604
+ process.stdout.write(result.stdout);
100906
101605
  }
100907
101606
  function findRepoRoot2(importerDir) {
100908
101607
  let current = importerDir;
100909
101608
  for (let depth = 0;depth <= 7; depth += 1) {
100910
- if (fileExistsSync(join57(current, "packages", "omo-senpi", "plugin", "package.json")))
101609
+ if (fileExistsSync(join60(current, "packages", "omo-senpi", "plugin", "package.json")))
100911
101610
  return current;
100912
- current = resolve16(current, "..");
101611
+ current = resolve18(current, "..");
100913
101612
  }
100914
101613
  throw new Error("Unable to locate packages/omo-senpi/plugin/package.json from installer module");
100915
101614
  }
100916
- function isPlainObject6(value) {
100917
- return typeof value === "object" && value !== null && !Array.isArray(value);
100918
- }
100919
- async function fileExists(path6) {
101615
+ async function fileExists2(path6) {
100920
101616
  try {
100921
- await access(path6, constants7.F_OK);
101617
+ await access2(path6, constants8.F_OK);
100922
101618
  return true;
100923
101619
  } catch (error51) {
100924
- if (isErrno(error51, "ENOENT"))
101620
+ if (isErrno2(error51, "ENOENT"))
100925
101621
  return false;
100926
101622
  throw error51;
100927
101623
  }
@@ -100929,7 +101625,7 @@ async function fileExists(path6) {
100929
101625
  function fileExistsSync(path6) {
100930
101626
  return existsSync30(path6);
100931
101627
  }
100932
- function isErrno(error51, code) {
101628
+ function isErrno2(error51, code) {
100933
101629
  return error51 instanceof Error && "code" in error51 && error51.code === code;
100934
101630
  }
100935
101631
  // packages/omo-opencode/src/cli/star-request.ts
@@ -100967,19 +101663,19 @@ init_provider_availability();
100967
101663
 
100968
101664
  // packages/omo-opencode/src/cli/config-manager/add-tui-plugin-to-tui-config.ts
100969
101665
  import { existsSync as existsSync32, mkdirSync as mkdirSync10, readFileSync as readFileSync15 } from "fs";
100970
- import { join as join59 } from "path";
101666
+ import { join as join62 } from "path";
100971
101667
 
100972
101668
  // packages/omo-opencode/src/cli/doctor/checks/tui-plugin-config.ts
100973
101669
  init_shared();
100974
101670
  import { existsSync as existsSync31, readFileSync as readFileSync14 } from "fs";
100975
- import { join as join58 } from "path";
101671
+ import { join as join61 } from "path";
100976
101672
  var TUI_SUBPATH = "tui";
100977
101673
  var TUI_EXPORT_SUBPATH = `./${TUI_SUBPATH}`;
100978
101674
  function fileEntryPackageJsonPath(entry) {
100979
101675
  let path6 = entry.slice("file:".length);
100980
101676
  if (path6.startsWith("//"))
100981
101677
  path6 = path6.slice(2);
100982
- return join58(path6, "package.json");
101678
+ return join61(path6, "package.json");
100983
101679
  }
100984
101680
  function packageJsonExportsTui(pkgJsonPath) {
100985
101681
  if (!existsSync31(pkgJsonPath))
@@ -101017,7 +101713,7 @@ function packageExportsTuiForServerEntry(entry) {
101017
101713
  const packageName = packageNameFromServerEntry(entry);
101018
101714
  if (packageName === null)
101019
101715
  return null;
101020
- return packageJsonExportsTui(join58(getOpenCodeConfigDir({ binary: "opencode" }), "node_modules", packageName, "package.json"));
101716
+ return packageJsonExportsTui(join61(getOpenCodeConfigDir({ binary: "opencode" }), "node_modules", packageName, "package.json"));
101021
101717
  }
101022
101718
  function isOurFilePluginEntry(entry) {
101023
101719
  if (typeof entry !== "string" || !entry.startsWith("file:"))
@@ -101082,7 +101778,7 @@ function detectServerPluginRegistration() {
101082
101778
  }
101083
101779
  }
101084
101780
  function detectTuiPluginRegistration() {
101085
- const tuiJsonPath = join58(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
101781
+ const tuiJsonPath = join61(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
101086
101782
  if (!existsSync31(tuiJsonPath)) {
101087
101783
  return {
101088
101784
  registered: false,
@@ -101238,10 +101934,10 @@ function readConfig(path6) {
101238
101934
  return null;
101239
101935
  }
101240
101936
  function readServerConfig(configDir) {
101241
- const jsoncPath = join59(configDir, "opencode.jsonc");
101937
+ const jsoncPath = join62(configDir, "opencode.jsonc");
101242
101938
  if (existsSync32(jsoncPath))
101243
101939
  return readConfig(jsoncPath);
101244
- const jsonPath = join59(configDir, "opencode.json");
101940
+ const jsonPath = join62(configDir, "opencode.json");
101245
101941
  if (existsSync32(jsonPath))
101246
101942
  return readConfig(jsonPath);
101247
101943
  return null;
@@ -101283,7 +101979,7 @@ function ensureTuiPluginEntry(opts = {}) {
101283
101979
  if (!desiredEntry) {
101284
101980
  return { changed: false, reason: "no-server-entry" };
101285
101981
  }
101286
- const tuiJsonPath = join59(configDir, "tui.json");
101982
+ const tuiJsonPath = join62(configDir, "tui.json");
101287
101983
  const { config: config3, malformed } = readTuiConfig(tuiJsonPath);
101288
101984
  if (malformed) {
101289
101985
  return { changed: false, reason: "malformed" };
@@ -101298,13 +101994,16 @@ function ensureTuiPluginEntry(opts = {}) {
101298
101994
  }
101299
101995
 
101300
101996
  // packages/omo-opencode/src/cli/install-ast-grep-sg.ts
101301
- import { homedir as homedir9 } from "os";
101302
- import { join as join60 } from "path";
101997
+ import { homedir as homedir10 } from "os";
101998
+ import { join as join63 } from "path";
101303
101999
 
101304
102000
  // packages/shared-skills/index.mjs
102001
+ import { existsSync as existsSync33 } from "fs";
101305
102002
  import { fileURLToPath as fileURLToPath2 } from "url";
102003
+ var SKILLS_PROBE_SPECIFIERS = ["./skills/", "../skills/", "../../skills/"];
101306
102004
  function sharedSkillsRootPath() {
101307
- return fileURLToPath2(new URL("./skills/", import.meta.url));
102005
+ const candidates = SKILLS_PROBE_SPECIFIERS.map((specifier) => fileURLToPath2(new URL(specifier, import.meta.url)));
102006
+ return candidates.find((candidate2) => existsSync33(candidate2)) ?? candidates[0];
101308
102007
  }
101309
102008
 
101310
102009
  // packages/omo-opencode/src/cli/install-ast-grep-sg.ts
@@ -101318,9 +102017,9 @@ function describeResult2(result) {
101318
102017
  }
101319
102018
  async function installAstGrepForOpenCode(options = {}) {
101320
102019
  const platform = options.platform ?? process.platform;
101321
- const baseDir = join60(options.homeDir ?? homedir9(), ".omo");
102020
+ const baseDir = join63(options.homeDir ?? homedir10(), ".omo");
101322
102021
  const targetDir = astGrepRuntimeDir(baseDir, platform, options.arch ?? process.arch);
101323
- const skillDir = join60(options.sharedSkillsRoot ?? sharedSkillsRootPath(), "ast-grep");
102022
+ const skillDir = join63(options.sharedSkillsRoot ?? sharedSkillsRootPath(), "ast-grep");
101324
102023
  const installer = options.installer ?? runAstGrepSkillInstall;
101325
102024
  try {
101326
102025
  const result = await installer({ platform, skillDir, targetDir });
@@ -103268,10 +103967,10 @@ function configureCleanupCommand(program2) {
103268
103967
  program2.command("cleanup").alias("uninstall").description("Clean managed Codex Light state and repair project-local legacy Codex artifacts").addOption(new Option("--platform <platform>", "Cleanup target platform: codex").choices(["codex"])).option("--codex-home <path>", "Codex home to clean (defaults to CODEX_HOME or ~/.codex)").option("--project <path>", "Project directory to inspect for project-local .codex artifacts").option("--json", "Output structured JSON result").addHelpText("after", `
103269
103968
  Examples:
103270
103969
  $ npx lazycodex-ai uninstall
103271
- $ omo uninstall --platform=codex
103970
+ $ omo-agent-toolkit uninstall --platform=codex
103272
103971
  $ npx lazycodex-ai cleanup
103273
- $ omo cleanup --platform=codex
103274
- $ omo uninstall --platform=codex --project /path/to/project
103972
+ $ omo-agent-toolkit cleanup --platform=codex
103973
+ $ omo-agent-toolkit uninstall --platform=codex --project /path/to/project
103275
103974
  `).action(async (options) => {
103276
103975
  const rootOptions = program2.opts();
103277
103976
  const platform = resolveCleanupPlatform({ platform: options.platform ?? rootOptions.platform });
@@ -104153,7 +104852,7 @@ function recordFields(value, fields) {
104153
104852
  }
104154
104853
  function modelInput(view) {
104155
104854
  const agents = isPlainRecord(view.agents) ? Object.fromEntries(Object.entries(view.agents).flatMap(([name, definition]) => {
104156
- const fields = recordFields(definition, ["description", "prompt", "model", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
104855
+ const fields = recordFields(definition, ["description", "prompt", "model", "models", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
104157
104856
  return fields === undefined ? [] : [[name, fields]];
104158
104857
  })) : undefined;
104159
104858
  const categories = isPlainRecord(view.categories) ? Object.fromEntries(Object.entries(view.categories).flatMap(([name, definition]) => {
@@ -104310,7 +105009,7 @@ function unknownPaths(schema2, value, path6) {
104310
105009
  }
104311
105010
  if (def.type === "union") {
104312
105011
  const candidates = (def.options ?? []).filter((option) => matchesShape(option, value)).map((option) => unknownPaths(option, value, path6));
104313
- return candidates.reduce((best, candidate) => best === undefined || candidate.length < best.length ? candidate : best, undefined) ?? [];
105012
+ return candidates.reduce((best, candidate2) => best === undefined || candidate2.length < best.length ? candidate2 : best, undefined) ?? [];
104314
105013
  }
104315
105014
  if (def.type === "intersection" && def.left !== undefined && def.right !== undefined) {
104316
105015
  return [...unknownPaths(def.left, value, path6), ...unknownPaths(def.right, value, path6)];
@@ -104416,6 +105115,7 @@ var AgentPermissionSchema = exports_external.object({
104416
105115
  // packages/omo-opencode/src/config/schema/agent-overrides.ts
104417
105116
  var AgentOverrideConfigSchema = exports_external.object({
104418
105117
  model: exports_external.string().optional(),
105118
+ models: exports_external.array(exports_external.union([exports_external.string(), FallbackModelObjectSchema])).optional(),
104419
105119
  fallback_models: FallbackModelsSchema.optional(),
104420
105120
  reasoning: OmoReasoningSchema.optional(),
104421
105121
  variant: exports_external.string().optional(),
@@ -104987,8 +105687,8 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
104987
105687
  });
104988
105688
  // packages/omo-opencode/src/config/validate.ts
104989
105689
  function shortPath(configPath) {
104990
- const candidate = relative7(process.cwd(), configPath);
104991
- return candidate.length > 0 ? candidate : configPath;
105690
+ const candidate2 = relative7(process.cwd(), configPath);
105691
+ return candidate2.length > 0 ? candidate2 : configPath;
104992
105692
  }
104993
105693
  function formatIssuePath(path6) {
104994
105694
  const formatted = path6.map((segment) => String(segment)).join(".");
@@ -105041,6 +105741,37 @@ function protectUserFields(config4, userConfig) {
105041
105741
  }
105042
105742
  };
105043
105743
  }
105744
+ function materializeAgentModelChains(config4) {
105745
+ if (config4.agents === undefined)
105746
+ return config4;
105747
+ let changed = false;
105748
+ const agents = Object.fromEntries(Object.entries(config4.agents).map(([name, agent2]) => {
105749
+ if (agent2?.models === undefined)
105750
+ return [name, agent2];
105751
+ const [primary, ...fallbacks] = agent2.models;
105752
+ const {
105753
+ models: _models,
105754
+ model: _model,
105755
+ fallback_models: _fallbackModels,
105756
+ reasoning: _reasoning,
105757
+ variant: _variant,
105758
+ reasoningEffort: _reasoningEffort,
105759
+ temperature: _temperature,
105760
+ top_p: _topP,
105761
+ maxTokens: _maxTokens,
105762
+ thinking: _thinking,
105763
+ ...rest
105764
+ } = agent2;
105765
+ const primarySettings = primary === undefined ? {} : typeof primary === "string" ? { model: primary } : primary;
105766
+ changed = true;
105767
+ return [name, {
105768
+ ...rest,
105769
+ ...primarySettings,
105770
+ fallback_models: fallbacks
105771
+ }];
105772
+ }));
105773
+ return changed ? { ...config4, agents } : config4;
105774
+ }
105044
105775
  function migrateRalphLoopConfig(config4) {
105045
105776
  const legacy = config4.ralph_loop;
105046
105777
  if (legacy === undefined)
@@ -105068,7 +105799,7 @@ function validatePluginConfig(directory, environment2 = process.env) {
105068
105799
  const firstFailingView = views.find((view) => view.messages.length > 0);
105069
105800
  const firstView = views[0];
105070
105801
  const userConfig = parseConfig(chain.protectedUserView);
105071
- const config4 = applyDisabledProviders(protectUserFields(mergeViews(views), userConfig));
105802
+ const config4 = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
105072
105803
  return {
105073
105804
  valid: messages.length === 0,
105074
105805
  messages,
@@ -105091,7 +105822,7 @@ var import_picocolors11 = __toESM(require_picocolors(), 1);
105091
105822
  // packages/omo-opencode/src/cli/run/opencode-binary-resolver.ts
105092
105823
  init_bun_which_shim();
105093
105824
  init_spawn_with_windows_hide();
105094
- import { delimiter as delimiter2, dirname as dirname21, posix as posix9, win32 as win325 } from "path";
105825
+ import { delimiter as delimiter2, dirname as dirname23, posix as posix9, win32 as win325 } from "path";
105095
105826
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
105096
105827
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
105097
105828
  function getCommandCandidates(platform) {
@@ -105141,15 +105872,15 @@ async function canExecuteBinary(binaryPath, spawn4 = spawnWithWindowsHide) {
105141
105872
  }
105142
105873
  async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe2 = canExecuteBinary, which2 = bunWhich, platform = process.platform) {
105143
105874
  const candidates = collectCandidateBinaryPaths(pathEnv, which2, platform);
105144
- for (const candidate of candidates) {
105145
- if (await probe2(candidate)) {
105146
- return candidate;
105875
+ for (const candidate2 of candidates) {
105876
+ if (await probe2(candidate2)) {
105877
+ return candidate2;
105147
105878
  }
105148
105879
  }
105149
105880
  return null;
105150
105881
  }
105151
105882
  function buildPathWithBinaryFirst(pathEnv, binaryPath) {
105152
- const preferredDir = dirname21(binaryPath);
105883
+ const preferredDir = dirname23(binaryPath);
105153
105884
  const existing = (pathEnv ?? "").split(delimiter2).filter((entry) => entry.length > 0 && entry !== preferredDir);
105154
105885
  return [preferredDir, ...existing].join(delimiter2);
105155
105886
  }
@@ -105318,7 +106049,7 @@ async function resolveSession(options) {
105318
106049
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
105319
106050
  const delay2 = retryDelayMs * attempt;
105320
106051
  console.log(import_picocolors12.default.dim(` Retrying in ${delay2}ms...`));
105321
- await new Promise((resolve17) => setTimeout(resolve17, delay2));
106052
+ await new Promise((resolve19) => setTimeout(resolve19, delay2));
105322
106053
  }
105323
106054
  continue;
105324
106055
  }
@@ -105329,7 +106060,7 @@ async function resolveSession(options) {
105329
106060
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
105330
106061
  const delay2 = retryDelayMs * attempt;
105331
106062
  console.log(import_picocolors12.default.dim(` Retrying in ${delay2}ms...`));
105332
- await new Promise((resolve17) => setTimeout(resolve17, delay2));
106063
+ await new Promise((resolve19) => setTimeout(resolve19, delay2));
105333
106064
  }
105334
106065
  }
105335
106066
  throw new Error("Failed to create session after all retries");
@@ -105727,9 +106458,9 @@ function isClosingFence(line, fence) {
105727
106458
  return run?.charAt(0) === fence.marker && run.length >= fence.length;
105728
106459
  }
105729
106460
  // packages/boulder-state/src/top-level-task.ts
105730
- import { existsSync as existsSync33, readFileSync as readFileSync16 } from "fs";
106461
+ import { existsSync as existsSync34, readFileSync as readFileSync16 } from "fs";
105731
106462
  function readCurrentTopLevelTask(planPath) {
105732
- if (!existsSync33(planPath)) {
106463
+ if (!existsSync34(planPath)) {
105733
106464
  return null;
105734
106465
  }
105735
106466
  try {
@@ -105740,13 +106471,13 @@ function readCurrentTopLevelTask(planPath) {
105740
106471
  }
105741
106472
  }
105742
106473
  // packages/boulder-state/src/storage/path.ts
105743
- import { existsSync as existsSync34 } from "fs";
105744
- import { isAbsolute as isAbsolute10, join as join61, relative as relative8, resolve as resolve17 } from "path";
106474
+ import { existsSync as existsSync35 } from "fs";
106475
+ import { isAbsolute as isAbsolute11, join as join64, relative as relative8, resolve as resolve19 } from "path";
105745
106476
  function getBoulderFilePath(directory) {
105746
- return join61(directory, BOULDER_DIR, BOULDER_FILE);
106477
+ return join64(directory, BOULDER_DIR, BOULDER_FILE);
105747
106478
  }
105748
106479
  function resolveTrackedPath(baseDirectory, trackedPath) {
105749
- return isAbsolute10(trackedPath) ? resolve17(trackedPath) : resolve17(baseDirectory, trackedPath);
106480
+ return isAbsolute11(trackedPath) ? resolve19(trackedPath) : resolve19(baseDirectory, trackedPath);
105750
106481
  }
105751
106482
  function resolveBoulderPlanPath(directory, state) {
105752
106483
  const absolutePlanPath = resolveTrackedPath(directory, state.active_plan);
@@ -105754,22 +106485,22 @@ function resolveBoulderPlanPath(directory, state) {
105754
106485
  if (!worktreePath) {
105755
106486
  return absolutePlanPath;
105756
106487
  }
105757
- const absoluteDirectory = resolve17(directory);
106488
+ const absoluteDirectory = resolve19(directory);
105758
106489
  const relativePlanPath = relative8(absoluteDirectory, absolutePlanPath);
105759
- if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute10(relativePlanPath)) {
106490
+ if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute11(relativePlanPath)) {
105760
106491
  return absolutePlanPath;
105761
106492
  }
105762
106493
  const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
105763
- const worktreePlanPath = resolve17(absoluteWorktreePath, relativePlanPath);
105764
- return existsSync34(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
106494
+ const worktreePlanPath = resolve19(absoluteWorktreePath, relativePlanPath);
106495
+ return existsSync35(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
105765
106496
  }
105766
106497
  function resolveBoulderPlanPathForWork(directory, work) {
105767
106498
  return resolveBoulderPlanPath(directory, work);
105768
106499
  }
105769
106500
  // packages/boulder-state/src/storage/plan-progress.ts
105770
- import { existsSync as existsSync35, readFileSync as readFileSync17, readdirSync as readdirSync7, statSync as statSync4 } from "fs";
106501
+ import { existsSync as existsSync36, readFileSync as readFileSync17, readdirSync as readdirSync7, statSync as statSync4 } from "fs";
105771
106502
  function getPlanProgress(planPath) {
105772
- if (!existsSync35(planPath)) {
106503
+ if (!existsSync36(planPath)) {
105773
106504
  return { total: 0, completed: 0, isComplete: false };
105774
106505
  }
105775
106506
  try {
@@ -105852,10 +106583,10 @@ function selectMirrorWork(state) {
105852
106583
  return sorted[0] ?? null;
105853
106584
  }
105854
106585
  // packages/boulder-state/src/storage/read-state.ts
105855
- import { existsSync as existsSync36, readFileSync as readFileSync18 } from "fs";
106586
+ import { existsSync as existsSync37, readFileSync as readFileSync18 } from "fs";
105856
106587
  function readBoulderState(directory) {
105857
106588
  const filePath = getBoulderFilePath(directory);
105858
- if (!existsSync36(filePath)) {
106589
+ if (!existsSync37(filePath)) {
105859
106590
  return null;
105860
106591
  }
105861
106592
  try {
@@ -105925,14 +106656,14 @@ init_state();
105925
106656
  // packages/omo-opencode/src/features/run-continuation-state/constants.ts
105926
106657
  var CONTINUATION_MARKER_DIR = ".omo/run-continuation";
105927
106658
  // packages/omo-opencode/src/features/run-continuation-state/storage.ts
105928
- import { existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync19, rmSync, writeFileSync as writeFileSync6 } from "fs";
105929
- import { join as join62 } from "path";
106659
+ import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync19, rmSync, writeFileSync as writeFileSync6 } from "fs";
106660
+ import { join as join65 } from "path";
105930
106661
  function getMarkerPath(directory, sessionID) {
105931
- return join62(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
106662
+ return join65(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
105932
106663
  }
105933
106664
  function readContinuationMarker(directory, sessionID) {
105934
106665
  const markerPath = getMarkerPath(directory, sessionID);
105935
- if (!existsSync37(markerPath))
106666
+ if (!existsSync38(markerPath))
105936
106667
  return null;
105937
106668
  try {
105938
106669
  const raw = readFileSync19(markerPath, "utf-8");
@@ -106001,7 +106732,7 @@ async function isSessionInBoulderLineage(input) {
106001
106732
  init_shared();
106002
106733
  init_compaction_marker();
106003
106734
  import { readFileSync as readFileSync20, readdirSync as readdirSync8 } from "fs";
106004
- import { join as join63 } from "path";
106735
+ import { join as join66 } from "path";
106005
106736
  var defaultSessionLastAgentDeps = {
106006
106737
  getMessageDir,
106007
106738
  isSqliteBackend,
@@ -106061,7 +106792,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
106061
106792
  try {
106062
106793
  const messages = readdirSync8(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
106063
106794
  try {
106064
- const content = readFileSync20(join63(messageDir, fileName), "utf-8");
106795
+ const content = readFileSync20(join66(messageDir, fileName), "utf-8");
106065
106796
  const parsed = JSON.parse(content);
106066
106797
  return {
106067
106798
  fileName,
@@ -106104,8 +106835,8 @@ init_agent_display_names();
106104
106835
 
106105
106836
  // packages/omo-opencode/src/hooks/ralph-loop/storage.ts
106106
106837
  init_frontmatter2();
106107
- import { existsSync as existsSync38, readFileSync as readFileSync21, writeFileSync as writeFileSync7, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12 } from "fs";
106108
- import { dirname as dirname22, join as join64 } from "path";
106838
+ import { existsSync as existsSync39, readFileSync as readFileSync21, writeFileSync as writeFileSync7, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12 } from "fs";
106839
+ import { dirname as dirname24, join as join67 } from "path";
106109
106840
 
106110
106841
  // packages/omo-opencode/src/hooks/ralph-loop/constants.ts
106111
106842
  var DEFAULT_STATE_FILE = ".omo/ralph-loop.local.md";
@@ -106114,11 +106845,11 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
106114
106845
 
106115
106846
  // packages/omo-opencode/src/hooks/ralph-loop/storage.ts
106116
106847
  function getStateFilePath(directory, customPath) {
106117
- return customPath ? join64(directory, customPath) : join64(directory, DEFAULT_STATE_FILE);
106848
+ return customPath ? join67(directory, customPath) : join67(directory, DEFAULT_STATE_FILE);
106118
106849
  }
106119
106850
  function readState(directory, customPath) {
106120
106851
  const filePath = getStateFilePath(directory, customPath);
106121
- if (!existsSync38(filePath)) {
106852
+ if (!existsSync39(filePath)) {
106122
106853
  return null;
106123
106854
  }
106124
106855
  try {
@@ -106348,7 +107079,7 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
106348
107079
  const secondaryMeaningfulWorkTimeoutMs = options.secondaryMeaningfulWorkTimeoutMs ?? DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS;
106349
107080
  const requireMeaningfulWork = options.requireMeaningfulWork ?? false;
106350
107081
  const now = options.now ?? Date.now;
106351
- const sleep = options.sleep ?? ((ms) => new Promise((resolve18) => setTimeout(resolve18, ms)));
107082
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve20) => setTimeout(resolve20, ms)));
106352
107083
  let consecutiveCompleteChecks = 0;
106353
107084
  let errorCycleCount = 0;
106354
107085
  let firstWorkTimestamp = null;
@@ -106513,7 +107244,7 @@ function createAbortError() {
106513
107244
  return error51;
106514
107245
  }
106515
107246
  function sleep(delayMs) {
106516
- return new Promise((resolve18) => setTimeout(resolve18, delayMs));
107247
+ return new Promise((resolve20) => setTimeout(resolve20, delayMs));
106517
107248
  }
106518
107249
  function hasPromptStartEvidence(eventState) {
106519
107250
  return eventState.mainSessionStarted || eventState.hasReceivedMeaningfulWork || eventState.messageCount > 0 || eventState.currentTool !== null;
@@ -106888,7 +107619,7 @@ var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
106888
107619
  async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
106889
107620
  const completed = await Promise.race([
106890
107621
  eventProcessor.then(() => true),
106891
- new Promise((resolve18) => setTimeout(() => resolve18(false), timeoutMs))
107622
+ new Promise((resolve20) => setTimeout(() => resolve20(false), timeoutMs))
106892
107623
  ]);
106893
107624
  }
106894
107625
  async function run(options) {
@@ -107214,14 +107945,14 @@ async function getLocalVersion(options = {}) {
107214
107945
  }
107215
107946
  }
107216
107947
  // packages/omo-opencode/src/cli/doctor/checks/system.ts
107217
- import { existsSync as existsSync49, readFileSync as readFileSync31 } from "fs";
107948
+ import { existsSync as existsSync50, readFileSync as readFileSync31 } from "fs";
107218
107949
 
107219
107950
  // packages/omo-opencode/src/cli/doctor/checks/system-binary.ts
107220
107951
  init_extract_semver();
107221
107952
  init_bun_which_shim();
107222
- import { existsSync as existsSync46, accessSync as accessSync4, constants as constants10 } from "fs";
107223
- import { homedir as homedir12 } from "os";
107224
- import { join as join71 } from "path";
107953
+ import { existsSync as existsSync47, accessSync as accessSync4, constants as constants11 } from "fs";
107954
+ import { homedir as homedir13 } from "os";
107955
+ import { join as join74 } from "path";
107225
107956
 
107226
107957
  // packages/omo-opencode/src/cli/doctor/framework/spawn-with-timeout.ts
107227
107958
  init_spawn_with_windows_hide();
@@ -107260,8 +107991,8 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
107260
107991
  const stdoutPromise = readSpawnStream(proc.stdout);
107261
107992
  const stderrPromise = readSpawnStream(proc.stderr);
107262
107993
  let timer;
107263
- const timeoutPromise = new Promise((resolve18) => {
107264
- timer = setTimeout(() => resolve18("timeout"), timeoutMs);
107994
+ const timeoutPromise = new Promise((resolve20) => {
107995
+ timer = setTimeout(() => resolve20("timeout"), timeoutMs);
107265
107996
  });
107266
107997
  const processPromise = (async () => {
107267
107998
  await proc.exited;
@@ -107298,7 +108029,7 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
107298
108029
  var WINDOWS_EXECUTABLE_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
107299
108030
  function isExecutable2(path12) {
107300
108031
  try {
107301
- accessSync4(path12, constants10.X_OK);
108032
+ accessSync4(path12, constants11.X_OK);
107302
108033
  return true;
107303
108034
  } catch (error51) {
107304
108035
  if (error51 instanceof Error) {
@@ -107308,22 +108039,22 @@ function isExecutable2(path12) {
107308
108039
  }
107309
108040
  }
107310
108041
  function getDesktopAppPaths(platform) {
107311
- const home = homedir12();
108042
+ const home = homedir13();
107312
108043
  switch (platform) {
107313
108044
  case "darwin":
107314
108045
  return [
107315
108046
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
107316
- join71(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
108047
+ join74(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
107317
108048
  ];
107318
108049
  case "win32": {
107319
108050
  const programFiles = process.env.ProgramFiles;
107320
108051
  const localAppData = process.env.LOCALAPPDATA;
107321
108052
  const paths2 = [];
107322
108053
  if (programFiles) {
107323
- paths2.push(join71(programFiles, "OpenCode", "OpenCode.exe"));
108054
+ paths2.push(join74(programFiles, "OpenCode", "OpenCode.exe"));
107324
108055
  }
107325
108056
  if (localAppData) {
107326
- paths2.push(join71(localAppData, "OpenCode", "OpenCode.exe"));
108057
+ paths2.push(join74(localAppData, "OpenCode", "OpenCode.exe"));
107327
108058
  }
107328
108059
  return paths2;
107329
108060
  }
@@ -107331,8 +108062,8 @@ function getDesktopAppPaths(platform) {
107331
108062
  return [
107332
108063
  "/usr/bin/opencode",
107333
108064
  "/usr/lib/opencode/opencode",
107334
- join71(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
107335
- join71(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
108065
+ join74(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
108066
+ join74(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
107336
108067
  ];
107337
108068
  default:
107338
108069
  return [];
@@ -107344,7 +108075,7 @@ function buildVersionCommand(binaryPath, platform) {
107344
108075
  }
107345
108076
  return [binaryPath, "--version"];
107346
108077
  }
107347
- function findDesktopBinary(platform = process.platform, checkExists = existsSync46) {
108078
+ function findDesktopBinary(platform = process.platform, checkExists = existsSync47) {
107348
108079
  for (const desktopPath of getDesktopAppPaths(platform)) {
107349
108080
  if (checkExists(desktopPath)) {
107350
108081
  return { binary: "opencode", path: desktopPath };
@@ -107352,7 +108083,7 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
107352
108083
  }
107353
108084
  return null;
107354
108085
  }
107355
- async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync46) {
108086
+ async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync47) {
107356
108087
  for (const binary of OPENCODE_BINARIES2) {
107357
108088
  const path12 = bunWhich(binary);
107358
108089
  if (path12 && checkExists(path12)) {
@@ -107364,7 +108095,7 @@ async function findOpenCodeBinary(platform = process.platform, checkExists = exi
107364
108095
  const candidates = getCommandCandidates2(platform);
107365
108096
  for (const entry of pathEnv.split(delimiter3).filter(Boolean)) {
107366
108097
  for (const command of candidates) {
107367
- const fullPath = join71(entry, command);
108098
+ const fullPath = join74(entry, command);
107368
108099
  if (checkExists(fullPath) && isExecutable2(fullPath)) {
107369
108100
  return { binary: command, path: fullPath };
107370
108101
  }
@@ -107410,12 +108141,12 @@ function compareVersions3(current, minimum) {
107410
108141
 
107411
108142
  // packages/omo-opencode/src/cli/doctor/checks/system-plugin.ts
107412
108143
  init_shared();
107413
- import { existsSync as existsSync47, readFileSync as readFileSync29 } from "fs";
108144
+ import { existsSync as existsSync48, readFileSync as readFileSync29 } from "fs";
107414
108145
  function detectConfigPath() {
107415
108146
  const paths2 = getOpenCodeConfigPaths({ binary: "opencode", version: null });
107416
- if (existsSync47(paths2.configJsonc))
108147
+ if (existsSync48(paths2.configJsonc))
107417
108148
  return paths2.configJsonc;
107418
- if (existsSync47(paths2.configJson))
108149
+ if (existsSync48(paths2.configJson))
107419
108150
  return paths2.configJson;
107420
108151
  return null;
107421
108152
  }
@@ -107503,36 +108234,36 @@ init_file_utils2();
107503
108234
  init_checker();
107504
108235
  init_auto_update_checker();
107505
108236
  init_package_json_locator();
107506
- import { existsSync as existsSync48, readFileSync as readFileSync30, readdirSync as readdirSync10 } from "fs";
108237
+ import { existsSync as existsSync49, readFileSync as readFileSync30, readdirSync as readdirSync10 } from "fs";
107507
108238
  import { createRequire as createRequire2 } from "module";
107508
- import { homedir as homedir13 } from "os";
107509
- import { join as join72 } from "path";
108239
+ import { homedir as homedir14 } from "os";
108240
+ import { join as join75 } from "path";
107510
108241
  import { fileURLToPath as fileURLToPath6 } from "url";
107511
108242
  init_shared();
107512
108243
  function getPlatformDefaultCacheDir(platform = process.platform) {
107513
108244
  if (platform === "darwin")
107514
- return join72(homedir13(), "Library", "Caches");
108245
+ return join75(homedir14(), "Library", "Caches");
107515
108246
  if (platform === "win32")
107516
- return process.env.LOCALAPPDATA ?? join72(homedir13(), "AppData", "Local");
107517
- return join72(homedir13(), ".cache");
108247
+ return process.env.LOCALAPPDATA ?? join75(homedir14(), "AppData", "Local");
108248
+ return join75(homedir14(), ".cache");
107518
108249
  }
107519
108250
  function resolveOpenCodeCacheDir() {
107520
108251
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
107521
108252
  if (xdgCacheHome)
107522
- return join72(xdgCacheHome, "opencode");
108253
+ return join75(xdgCacheHome, "opencode");
107523
108254
  const fromShared = getOpenCodeCacheDir();
107524
- const platformDefault = join72(getPlatformDefaultCacheDir(), "opencode");
107525
- if (existsSync48(fromShared) || !existsSync48(platformDefault))
108255
+ const platformDefault = join75(getPlatformDefaultCacheDir(), "opencode");
108256
+ if (existsSync49(fromShared) || !existsSync49(platformDefault))
107526
108257
  return fromShared;
107527
108258
  return platformDefault;
107528
108259
  }
107529
108260
  function resolveExistingDir(dirPath) {
107530
- if (!existsSync48(dirPath))
108261
+ if (!existsSync49(dirPath))
107531
108262
  return dirPath;
107532
108263
  return resolveSymlink(dirPath);
107533
108264
  }
107534
108265
  function readPackageJson(filePath) {
107535
- if (!existsSync48(filePath))
108266
+ if (!existsSync49(filePath))
107536
108267
  return null;
107537
108268
  try {
107538
108269
  const content = readFileSync30(filePath, "utf-8");
@@ -107553,34 +108284,34 @@ function normalizeVersion(value) {
107553
108284
  function createPackageCandidates(rootDir) {
107554
108285
  return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
107555
108286
  packageName,
107556
- installedPackagePath: join72(rootDir, "node_modules", packageName, "package.json")
108287
+ installedPackagePath: join75(rootDir, "node_modules", packageName, "package.json")
107557
108288
  }));
107558
108289
  }
107559
108290
  function createTaggedInstallCandidates(rootDir) {
107560
- const packagesDir = join72(rootDir, "packages");
107561
- if (!existsSync48(packagesDir))
108291
+ const packagesDir = join75(rootDir, "packages");
108292
+ if (!existsSync49(packagesDir))
107562
108293
  return [];
107563
108294
  const candidates = [];
107564
108295
  for (const entryName of readdirSync10(packagesDir).sort()) {
107565
108296
  const packageName = ACCEPTED_PACKAGE_NAMES.find((name) => entryName.startsWith(`${name}@`));
107566
108297
  if (packageName === undefined)
107567
108298
  continue;
107568
- const installDir = join72(packagesDir, entryName);
108299
+ const installDir = join75(packagesDir, entryName);
107569
108300
  candidates.push({
107570
108301
  cacheDir: installDir,
107571
- cachePackagePath: join72(installDir, "package.json"),
108302
+ cachePackagePath: join75(installDir, "package.json"),
107572
108303
  packageCandidates: [
107573
108304
  {
107574
108305
  packageName,
107575
- installedPackagePath: join72(installDir, "node_modules", packageName, "package.json")
108306
+ installedPackagePath: join75(installDir, "node_modules", packageName, "package.json")
107576
108307
  }
107577
108308
  ]
107578
108309
  });
107579
108310
  }
107580
108311
  return candidates;
107581
108312
  }
107582
- function selectInstalledPackage(candidate) {
107583
- return candidate.packageCandidates.find((packageCandidate) => existsSync48(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
108313
+ function selectInstalledPackage(candidate2) {
108314
+ return candidate2.packageCandidates.find((packageCandidate) => existsSync49(packageCandidate.installedPackagePath)) ?? candidate2.packageCandidates[0];
107584
108315
  }
107585
108316
  function getExpectedVersion(cachePackage, packageName) {
107586
108317
  return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
@@ -107591,7 +108322,7 @@ function resolveInstalledPackageJsonPath() {
107591
108322
  for (const packageName of ACCEPTED_PACKAGE_NAMES) {
107592
108323
  try {
107593
108324
  const packageJsonPath = require2.resolve(`${packageName}/package.json`);
107594
- if (existsSync48(packageJsonPath)) {
108325
+ if (existsSync49(packageJsonPath)) {
107595
108326
  return { packageName, packageJsonPath };
107596
108327
  }
107597
108328
  } catch {
@@ -107617,22 +108348,22 @@ function getLoadedPluginVersion() {
107617
108348
  const candidates = [
107618
108349
  {
107619
108350
  cacheDir: configDir,
107620
- cachePackagePath: join72(configDir, "package.json"),
108351
+ cachePackagePath: join75(configDir, "package.json"),
107621
108352
  packageCandidates: createPackageCandidates(configDir)
107622
108353
  },
107623
108354
  ...createTaggedInstallCandidates(configDir),
107624
108355
  {
107625
108356
  cacheDir,
107626
- cachePackagePath: join72(cacheDir, "package.json"),
108357
+ cachePackagePath: join75(cacheDir, "package.json"),
107627
108358
  packageCandidates: createPackageCandidates(cacheDir)
107628
108359
  },
107629
108360
  ...createTaggedInstallCandidates(cacheDir)
107630
108361
  ];
107631
- const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync48(packageCandidate.installedPackagePath))) ?? candidates[0];
108362
+ const selectedCandidate = candidates.find((candidate2) => candidate2.packageCandidates.some((packageCandidate) => existsSync49(packageCandidate.installedPackagePath))) ?? candidates[0];
107632
108363
  const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
107633
108364
  const selectedPackage = selectInstalledPackage(selectedCandidate);
107634
108365
  const candidateInstalledPath = selectedPackage.installedPackagePath;
107635
- const candidateExists = existsSync48(candidateInstalledPath);
108366
+ const candidateExists = existsSync49(candidateInstalledPath);
107636
108367
  const resolvedFallback = candidateExists ? null : resolveInstalledPackageJsonPath();
107637
108368
  const installedPackagePath = resolvedFallback?.packageJsonPath ?? candidateInstalledPath;
107638
108369
  const resolvedPackageName = resolvedFallback?.packageName ?? selectedPackage.packageName;
@@ -107668,7 +108399,7 @@ var defaultDeps6 = {
107668
108399
  getLoadedPluginVersion,
107669
108400
  getLatestPluginVersion,
107670
108401
  getSuggestedInstallTag,
107671
- configExists: existsSync49,
108402
+ configExists: existsSync50,
107672
108403
  readConfigFile: (path12) => readFileSync31(path12, "utf-8"),
107673
108404
  parseConfigContent: (content) => parseJsonc(content)
107674
108405
  };
@@ -107814,23 +108545,23 @@ async function checkSystem(deps = defaultDeps6) {
107814
108545
 
107815
108546
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-cache.ts
107816
108547
  init_shared();
107817
- import { existsSync as existsSync50, readFileSync as readFileSync32 } from "fs";
107818
- import { homedir as homedir14 } from "os";
107819
- import { join as join73 } from "path";
108548
+ import { existsSync as existsSync51, readFileSync as readFileSync32 } from "fs";
108549
+ import { homedir as homedir15 } from "os";
108550
+ import { join as join76 } from "path";
107820
108551
  function getUserConfigDir2() {
107821
108552
  const xdgConfig = process.env.XDG_CONFIG_HOME;
107822
108553
  if (xdgConfig)
107823
- return join73(xdgConfig, "opencode");
107824
- return join73(homedir14(), ".config", "opencode");
108554
+ return join76(xdgConfig, "opencode");
108555
+ return join76(homedir15(), ".config", "opencode");
107825
108556
  }
107826
108557
  function loadCustomProviderNames() {
107827
108558
  const configDir = getUserConfigDir2();
107828
108559
  const candidatePaths = [
107829
- join73(configDir, "opencode.json"),
107830
- join73(configDir, "opencode.jsonc")
108560
+ join76(configDir, "opencode.json"),
108561
+ join76(configDir, "opencode.jsonc")
107831
108562
  ];
107832
108563
  for (const configPath of candidatePaths) {
107833
- if (!existsSync50(configPath))
108564
+ if (!existsSync51(configPath))
107834
108565
  continue;
107835
108566
  try {
107836
108567
  const content = readFileSync32(configPath, "utf-8");
@@ -107848,9 +108579,9 @@ function loadCustomProviderNames() {
107848
108579
  return [];
107849
108580
  }
107850
108581
  function loadAvailableModelsFromCache() {
107851
- const cacheFile = join73(getOpenCodeCacheDir(), "models.json");
108582
+ const cacheFile = join76(getOpenCodeCacheDir(), "models.json");
107852
108583
  const customProviders = loadCustomProviderNames();
107853
- if (!existsSync50(cacheFile)) {
108584
+ if (!existsSync51(cacheFile)) {
107854
108585
  if (customProviders.length > 0) {
107855
108586
  return { providers: customProviders, modelCount: 0, cacheExists: true };
107856
108587
  }
@@ -107910,7 +108641,7 @@ function loadOmoConfig2() {
107910
108641
 
107911
108642
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-details.ts
107912
108643
  init_shared();
107913
- import { join as join74 } from "path";
108644
+ import { join as join77 } from "path";
107914
108645
 
107915
108646
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-variant.ts
107916
108647
  function formatModelWithVariant(model, variant) {
@@ -107952,7 +108683,7 @@ function formatCapabilityResolutionLabel(mode) {
107952
108683
  }
107953
108684
  function buildModelResolutionDetails(options) {
107954
108685
  const details = [];
107955
- const cacheFile = join74(getOpenCodeCacheDir(), "models.json");
108686
+ const cacheFile = join77(getOpenCodeCacheDir(), "models.json");
107956
108687
  details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
107957
108688
  details.push("");
107958
108689
  if (options.available.cacheExists) {
@@ -108261,24 +108992,25 @@ async function checkConfig() {
108261
108992
 
108262
108993
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
108263
108994
  init_main();
108264
- import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
108265
- import { join as join75 } from "path";
108995
+ import { existsSync as existsSync52, readFileSync as readFileSync33 } from "fs";
108996
+ import { join as join78 } from "path";
108266
108997
  var CANONICAL_REPLACEMENT = new Map([
108267
108998
  ["variant", "reasoning"],
108268
108999
  ["reasoningEffort", "reasoning"],
108269
- ["thinking", "reasoning"],
109000
+ ["thinking", 'reasoning: "off" or provider_options.thinking'],
108270
109001
  ["textVerbosity", "provider_options.textVerbosity"],
108271
109002
  ["fallback_models", "models"]
108272
109003
  ]);
108273
109004
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
108274
- function isRecord10(value) {
109005
+ var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
109006
+ function isRecord11(value) {
108275
109007
  return value !== null && typeof value === "object" && !Array.isArray(value);
108276
109008
  }
108277
109009
  function isHarnessBlock(key) {
108278
109010
  return key.startsWith("[") && key.endsWith("]");
108279
109011
  }
108280
109012
  function collectIssues(configPath, value, prefix) {
108281
- if (!isRecord10(value))
109013
+ if (!isRecord11(value))
108282
109014
  return [];
108283
109015
  const issues = [];
108284
109016
  for (const [key, child] of Object.entries(value)) {
@@ -108286,7 +109018,7 @@ function collectIssues(configPath, value, prefix) {
108286
109018
  const replacement = CANONICAL_REPLACEMENT.get(key);
108287
109019
  if (replacement !== undefined) {
108288
109020
  issues.push({
108289
- title: "Deprecated reasoning config key",
109021
+ title: "Deprecated config key",
108290
109022
  description: `${configPath}: ${path12}`,
108291
109023
  fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
108292
109024
  severity: "warning",
@@ -108294,7 +109026,9 @@ function collectIssues(configPath, value, prefix) {
108294
109026
  });
108295
109027
  continue;
108296
109028
  }
108297
- if (!isRecord10(child))
109029
+ if (!isRecord11(child))
109030
+ continue;
109031
+ if (PASSTHROUGH_CONTAINERS.has(key))
108298
109032
  continue;
108299
109033
  if (prefix.length === 0 && key === "profiles") {
108300
109034
  for (const profile2 of Object.values(child)) {
@@ -108302,6 +109036,8 @@ function collectIssues(configPath, value, prefix) {
108302
109036
  }
108303
109037
  continue;
108304
109038
  }
109039
+ if (key === "[opencode]")
109040
+ continue;
108305
109041
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
108306
109042
  issues.push(...collectIssues(configPath, child, path12));
108307
109043
  }
@@ -108312,13 +109048,13 @@ function userConfigPaths() {
108312
109048
  const home = process.env.HOME ?? process.env.USERPROFILE;
108313
109049
  if (home === undefined || home.length === 0)
108314
109050
  return [];
108315
- return [join75(home, ".omo", "omo.jsonc"), join75(home, ".omo", "omo.json")];
109051
+ return [join78(home, ".omo", "omo.jsonc"), join78(home, ".omo", "omo.json")];
108316
109052
  }
108317
109053
  async function checkDeprecatedReasoningKeys() {
108318
109054
  const issues = [];
108319
109055
  const scanned = [];
108320
109056
  for (const configPath of userConfigPaths()) {
108321
- if (!existsSync51(configPath))
109057
+ if (!existsSync52(configPath))
108322
109058
  continue;
108323
109059
  scanned.push(configPath);
108324
109060
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
@@ -108327,7 +109063,7 @@ async function checkDeprecatedReasoningKeys() {
108327
109063
  return {
108328
109064
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
108329
109065
  status: issues.length > 0 ? "warn" : "pass",
108330
- message: issues.length > 0 ? `${issues.length} deprecated reasoning key(s) found` : "No deprecated reasoning keys found",
109066
+ message: issues.length > 0 ? `${issues.length} deprecated config key(s) found` : "No deprecated config keys found",
108331
109067
  ...scanned.length > 0 ? { details: scanned.map((path12) => `Scanned: ${path12}`) } : {},
108332
109068
  issues
108333
109069
  };
@@ -108335,28 +109071,28 @@ async function checkDeprecatedReasoningKeys() {
108335
109071
 
108336
109072
  // packages/omo-opencode/src/cli/doctor/checks/dependencies.ts
108337
109073
  init_src2();
108338
- import { existsSync as existsSync52 } from "fs";
109074
+ import { existsSync as existsSync53 } from "fs";
108339
109075
  import { createRequire as createRequire3 } from "module";
108340
- import { homedir as homedir16 } from "os";
108341
- import { dirname as dirname27, join as join77 } from "path";
109076
+ import { homedir as homedir17 } from "os";
109077
+ import { dirname as dirname29, join as join80 } from "path";
108342
109078
 
108343
109079
  // packages/omo-opencode/src/hooks/comment-checker/downloader.ts
108344
- import { join as join76 } from "path";
108345
- import { homedir as homedir15, tmpdir as tmpdir4 } from "os";
109080
+ import { join as join79 } from "path";
109081
+ import { homedir as homedir16, tmpdir as tmpdir4 } from "os";
108346
109082
  init_binary_downloader();
108347
109083
  init_logger2();
108348
109084
  init_plugin_identity();
108349
109085
  var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
108350
- var DEBUG_FILE = join76(tmpdir4(), "comment-checker-debug.log");
109086
+ var DEBUG_FILE = join79(tmpdir4(), "comment-checker-debug.log");
108351
109087
  function getCacheDir2() {
108352
109088
  if (process.platform === "win32") {
108353
109089
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
108354
- const base2 = localAppData || join76(homedir15(), "AppData", "Local");
108355
- return join76(base2, CACHE_DIR_NAME, "bin");
109090
+ const base2 = localAppData || join79(homedir16(), "AppData", "Local");
109091
+ return join79(base2, CACHE_DIR_NAME, "bin");
108356
109092
  }
108357
109093
  const xdgCache = process.env.XDG_CACHE_HOME;
108358
- const base = xdgCache || join76(homedir15(), ".cache");
108359
- return join76(base, CACHE_DIR_NAME, "bin");
109094
+ const base = xdgCache || join79(homedir16(), ".cache");
109095
+ return join79(base, CACHE_DIR_NAME, "bin");
108360
109096
  }
108361
109097
  function getBinaryName() {
108362
109098
  return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
@@ -108406,7 +109142,7 @@ async function getBinaryVersion(binary) {
108406
109142
  }
108407
109143
  }
108408
109144
  async function checkAstGrepCli() {
108409
- const runtimeDir = astGrepRuntimeDir(join77(homedir16(), ".omo"));
109145
+ const runtimeDir = astGrepRuntimeDir(join80(homedir17(), ".omo"));
108410
109146
  const sgPath = findSgBinarySync({ runtimeDir });
108411
109147
  if (sgPath === null) {
108412
109148
  return {
@@ -108435,12 +109171,12 @@ function findCommentCheckerPackageBinary(baseDirOverride, resolvePackageJsonPath
108435
109171
  const binaryName = process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
108436
109172
  const platformKey = `${process.platform}-${process.arch === "x64" ? "x64" : process.arch}`;
108437
109173
  try {
108438
- const packageDir = baseDirOverride ?? dirname27(resolvePackageJsonPath());
108439
- const vendorPath = join77(packageDir, "vendor", platformKey, binaryName);
108440
- if (existsSync52(vendorPath))
109174
+ const packageDir = baseDirOverride ?? dirname29(resolvePackageJsonPath());
109175
+ const vendorPath = join80(packageDir, "vendor", platformKey, binaryName);
109176
+ if (existsSync53(vendorPath))
108441
109177
  return vendorPath;
108442
- const binPath = join77(packageDir, "bin", binaryName);
108443
- if (existsSync52(binPath))
109178
+ const binPath = join80(packageDir, "bin", binaryName);
109179
+ if (existsSync53(binPath))
108444
109180
  return binPath;
108445
109181
  } catch (error51) {
108446
109182
  if (!(error51 instanceof Error) && !isModuleResolutionFailure(error51))
@@ -108586,8 +109322,8 @@ async function getGhCliInfo(dependencies = {}) {
108586
109322
  // packages/omo-opencode/src/mcp/lsp.ts
108587
109323
  init_zod();
108588
109324
  init_opencode_config_dir();
108589
- import { existsSync as existsSync53, readFileSync as readFileSync34 } from "fs";
108590
- import { delimiter as delimiter3, dirname as dirname28, resolve as resolve19 } from "path";
109325
+ import { existsSync as existsSync54, readFileSync as readFileSync34 } from "fs";
109326
+ import { delimiter as delimiter3, dirname as dirname30, resolve as resolve21 } from "path";
108591
109327
  import { fileURLToPath as fileURLToPath7 } from "url";
108592
109328
 
108593
109329
  // packages/omo-opencode/src/mcp/cli-suffix.ts
@@ -108634,7 +109370,7 @@ function resolveRuntimeExecutable(commandName, options = {}) {
108634
109370
  }
108635
109371
 
108636
109372
  // packages/omo-opencode/src/mcp/shared/ancestor-cli-resolver.ts
108637
- import { resolve as resolve18 } from "path";
109373
+ import { resolve as resolve20 } from "path";
108638
109374
  function resolveJavaScriptRuntime(resolveExecutable) {
108639
109375
  const node = resolveExecutable("node");
108640
109376
  return node.available ? node : resolveExecutable("bun");
@@ -108642,9 +109378,9 @@ function resolveJavaScriptRuntime(resolveExecutable) {
108642
109378
  function createAncestorCliCandidates(options) {
108643
109379
  const candidates = [];
108644
109380
  const seenPaths = new Set;
108645
- let currentDirectory = resolve18(options.startDirectory);
109381
+ let currentDirectory = resolve20(options.startDirectory);
108646
109382
  while (true) {
108647
- const distCliPath = resolve18(currentDirectory, options.packageRel, options.distCliRel);
109383
+ const distCliPath = resolve20(currentDirectory, options.packageRel, options.distCliRel);
108648
109384
  if (!seenPaths.has(distCliPath)) {
108649
109385
  const runtime5 = resolveJavaScriptRuntime(options.resolveExecutable);
108650
109386
  seenPaths.add(distCliPath);
@@ -108656,7 +109392,7 @@ function createAncestorCliCandidates(options) {
108656
109392
  runtimeAvailable: runtime5.available
108657
109393
  });
108658
109394
  }
108659
- const sourceCliPath = resolve18(currentDirectory, options.packageRel, options.sourceCliRel);
109395
+ const sourceCliPath = resolve20(currentDirectory, options.packageRel, options.sourceCliRel);
108660
109396
  if (!seenPaths.has(sourceCliPath)) {
108661
109397
  const runtime5 = options.resolveExecutable("bun");
108662
109398
  const sourceCandidateAvailable = options.isSourceCandidateAvailable?.({
@@ -108673,7 +109409,7 @@ function createAncestorCliCandidates(options) {
108673
109409
  runtimeAvailable: runtime5.available
108674
109410
  });
108675
109411
  }
108676
- const parentDirectory = resolve18(currentDirectory, "..");
109412
+ const parentDirectory = resolve20(currentDirectory, "..");
108677
109413
  if (parentDirectory === currentDirectory)
108678
109414
  return candidates;
108679
109415
  currentDirectory = parentDirectory;
@@ -108718,7 +109454,7 @@ var LSP_BOOTSTRAP_SCRIPT = [
108718
109454
  ].join(";");
108719
109455
  function getModuleDirectory(moduleUrl) {
108720
109456
  try {
108721
- return dirname28(fileURLToPath7(moduleUrl));
109457
+ return dirname30(fileURLToPath7(moduleUrl));
108722
109458
  } catch (error51) {
108723
109459
  if (!(error51 instanceof Error))
108724
109460
  throw error51;
@@ -108726,11 +109462,11 @@ function getModuleDirectory(moduleUrl) {
108726
109462
  }
108727
109463
  }
108728
109464
  function findBootstrapRoot(candidates, pathExists) {
108729
- return candidates.find((candidate) => pathExists(resolve19(candidate.root, "package.json")))?.root ?? process.cwd();
109465
+ return candidates.find((candidate2) => pathExists(resolve21(candidate2.root, "package.json")))?.root ?? process.cwd();
108730
109466
  }
108731
109467
  function readDaemonPackageVersion(root) {
108732
109468
  try {
108733
- const packageJson = JSON.parse(readFileSync34(resolve19(root, PACKAGE_REL, "package.json"), "utf-8"));
109469
+ const packageJson = JSON.parse(readFileSync34(resolve21(root, PACKAGE_REL, "package.json"), "utf-8"));
108734
109470
  return DaemonPackageSchema.parse(packageJson).version;
108735
109471
  } catch (error51) {
108736
109472
  if (!(error51 instanceof Error))
@@ -108742,17 +109478,17 @@ function createBootstrapCandidate(root, pathExists, resolveExecutable) {
108742
109478
  const runtime5 = resolveJavaScriptRuntime(resolveExecutable);
108743
109479
  const bun = resolveExecutable("bun");
108744
109480
  const npm = resolveExecutable("npm");
108745
- const packageManifestPath = resolve19(root, PACKAGE_REL, "package.json");
109481
+ const packageManifestPath = resolve21(root, PACKAGE_REL, "package.json");
108746
109482
  return {
108747
109483
  command: [runtime5.command, "-e", LSP_BOOTSTRAP_SCRIPT, root, npm.command, bun.command],
108748
109484
  root,
108749
- path: resolve19(root, PACKAGE_REL, DIST_CLI_REL),
109485
+ path: resolve21(root, PACKAGE_REL, DIST_CLI_REL),
108750
109486
  exists: runtime5.available && npm.available && pathExists(packageManifestPath),
108751
109487
  runtimeAvailable: runtime5.available
108752
109488
  };
108753
109489
  }
108754
109490
  function resolveLspCommand(options = {}) {
108755
- const pathExists = options.exists ?? existsSync53;
109491
+ const pathExists = options.exists ?? existsSync54;
108756
109492
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
108757
109493
  const moduleDirectory = getModuleDirectory(options.moduleUrl ?? import.meta.url);
108758
109494
  const candidates = moduleDirectory ? createAncestorCliCandidates({
@@ -108762,13 +109498,13 @@ function resolveLspCommand(options = {}) {
108762
109498
  sourceCliRel: SOURCE_CLI_REL,
108763
109499
  pathExists,
108764
109500
  resolveExecutable,
108765
- isSourceCandidateAvailable: ({ root }) => pathExists(resolve19(root, LSP_TOOLS_PACKAGE_REL, DIST_CLI_REL)) && readDaemonPackageVersion(root) !== null
109501
+ isSourceCandidateAvailable: ({ root }) => pathExists(resolve21(root, LSP_TOOLS_PACKAGE_REL, DIST_CLI_REL)) && readDaemonPackageVersion(root) !== null
108766
109502
  }) : [];
108767
- const distCandidate = candidates.find((candidate) => hasCliSuffix(candidate.path, DIST_CLI_REL) && candidate.exists);
109503
+ const distCandidate = candidates.find((candidate2) => hasCliSuffix(candidate2.path, DIST_CLI_REL) && candidate2.exists);
108768
109504
  if (distCandidate) {
108769
109505
  return distCandidate;
108770
109506
  }
108771
- const sourceCandidate = candidates.find((candidate) => hasCliSuffix(candidate.path, SOURCE_CLI_REL) && candidate.exists);
109507
+ const sourceCandidate = candidates.find((candidate2) => hasCliSuffix(candidate2.path, SOURCE_CLI_REL) && candidate2.exists);
108772
109508
  if (sourceCandidate) {
108773
109509
  return sourceCandidate;
108774
109510
  }
@@ -108776,17 +109512,18 @@ function resolveLspCommand(options = {}) {
108776
109512
  }
108777
109513
  function createLspMcpConfig(options = {}) {
108778
109514
  const resolvedCommand = resolveLspCommand(options);
108779
- const cwd = resolve19(options.cwd ?? process.cwd());
109515
+ const cwd = resolve21(options.cwd ?? process.cwd());
108780
109516
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
108781
109517
  const sourceVersion = hasCliSuffix(resolvedCommand.path, SOURCE_CLI_REL) ? readDaemonPackageVersion(resolvedCommand.root) : null;
108782
109518
  return {
108783
109519
  type: "local",
108784
109520
  command: resolvedCommand.command,
108785
109521
  enabled: resolvedCommand.exists,
109522
+ cwd,
108786
109523
  environment: {
108787
- LSP_TOOLS_MCP_PROJECT_CONFIG: PROJECT_LSP_CONFIGS.map((configPath) => resolve19(cwd, configPath)).join(delimiter3),
108788
- LSP_TOOLS_MCP_USER_CONFIG: resolve19(configDir, "lsp.json"),
108789
- LSP_TOOLS_MCP_INSTALL_DECISIONS: resolve19(configDir, "lsp-install-decisions.json"),
109524
+ LSP_TOOLS_MCP_PROJECT_CONFIG: PROJECT_LSP_CONFIGS.map((configPath) => resolve21(cwd, configPath)).join(delimiter3),
109525
+ LSP_TOOLS_MCP_USER_CONFIG: resolve21(configDir, "lsp.json"),
109526
+ LSP_TOOLS_MCP_INSTALL_DECISIONS: resolve21(configDir, "lsp-install-decisions.json"),
108790
109527
  ...sourceVersion ? {
108791
109528
  [OMO_LSP_DAEMON_CLI]: resolvedCommand.path,
108792
109529
  [OMO_LSP_DAEMON_VERSION]: sourceVersion
@@ -108811,21 +109548,21 @@ function getInstalledLspServers(options = {}) {
108811
109548
 
108812
109549
  // packages/omo-opencode/src/cli/doctor/checks/tools-mcp.ts
108813
109550
  init_shared();
108814
- import { existsSync as existsSync54, readFileSync as readFileSync35 } from "fs";
108815
- import { homedir as homedir17 } from "os";
108816
- import { join as join78 } from "path";
109551
+ import { existsSync as existsSync55, readFileSync as readFileSync35 } from "fs";
109552
+ import { homedir as homedir18 } from "os";
109553
+ import { join as join81 } from "path";
108817
109554
  var BUILTIN_MCP_SERVERS = ["websearch", "context7", "grep_app", "lsp"];
108818
109555
  function getMcpConfigPaths() {
108819
109556
  return [
108820
- join78(homedir17(), ".claude", ".mcp.json"),
108821
- join78(process.cwd(), ".mcp.json"),
108822
- join78(process.cwd(), ".claude", ".mcp.json")
109557
+ join81(homedir18(), ".claude", ".mcp.json"),
109558
+ join81(process.cwd(), ".mcp.json"),
109559
+ join81(process.cwd(), ".claude", ".mcp.json")
108823
109560
  ];
108824
109561
  }
108825
109562
  function loadUserMcpConfig() {
108826
109563
  const servers = {};
108827
109564
  for (const configPath of getMcpConfigPaths()) {
108828
- if (!existsSync54(configPath))
109565
+ if (!existsSync55(configPath))
108829
109566
  continue;
108830
109567
  try {
108831
109568
  const content = readFileSync35(configPath, "utf-8");
@@ -108963,12 +109700,12 @@ async function checkTools() {
108963
109700
 
108964
109701
  // packages/omo-opencode/src/cli/doctor/checks/telemetry.ts
108965
109702
  init_src5();
108966
- import { existsSync as existsSync55, readFileSync as readFileSync36 } from "fs";
109703
+ import { existsSync as existsSync56, readFileSync as readFileSync36 } from "fs";
108967
109704
  function isTelemetryState(value) {
108968
109705
  return value !== null && typeof value === "object" && !Array.isArray(value);
108969
109706
  }
108970
109707
  function readLastActiveDay(stateFilePath) {
108971
- if (!existsSync55(stateFilePath)) {
109708
+ if (!existsSync56(stateFilePath)) {
108972
109709
  return "never";
108973
109710
  }
108974
109711
  let parsed;
@@ -109031,17 +109768,17 @@ async function probeBinary(cmd, args, spawnImpl) {
109031
109768
  }
109032
109769
 
109033
109770
  // packages/team-core/src/team-registry/paths.ts
109034
- import { homedir as homedir18 } from "os";
109771
+ import { homedir as homedir19 } from "os";
109035
109772
  import path12 from "path";
109036
109773
  function resolveBaseDir(config4) {
109037
- return expandHomeDirectory(config4.base_dir ?? path12.join(homedir18(), ".omo"));
109774
+ return expandHomeDirectory(config4.base_dir ?? path12.join(homedir19(), ".omo"));
109038
109775
  }
109039
109776
  function expandHomeDirectory(directoryPath3) {
109040
109777
  if (directoryPath3 === "~") {
109041
- return homedir18();
109778
+ return homedir19();
109042
109779
  }
109043
109780
  if (directoryPath3.startsWith("~/") || directoryPath3.startsWith("~\\")) {
109044
- return path12.join(homedir18(), directoryPath3.slice(2));
109781
+ return path12.join(homedir19(), directoryPath3.slice(2));
109045
109782
  }
109046
109783
  return directoryPath3;
109047
109784
  }
@@ -109098,10 +109835,10 @@ async function pathExists(dir) {
109098
109835
 
109099
109836
  // packages/omo-opencode/src/cli/doctor/checks/codex.ts
109100
109837
  init_src2();
109101
- import { existsSync as existsSync56 } from "fs";
109102
- import { lstat as lstat14, readdir as readdir12, readFile as readFile24 } from "fs/promises";
109103
- import { homedir as homedir19 } from "os";
109104
- import { basename as basename11, join as join79, resolve as resolve20 } from "path";
109838
+ import { existsSync as existsSync57 } from "fs";
109839
+ import { lstat as lstat15, readdir as readdir14, readFile as readFile27 } from "fs/promises";
109840
+ import { homedir as homedir20 } from "os";
109841
+ import { basename as basename11, join as join82, resolve as resolve22 } from "path";
109105
109842
  // packages/omo-opencode/package.json
109106
109843
  var package_default3 = {
109107
109844
  name: "@oh-my-opencode/omo-opencode",
@@ -109156,7 +109893,7 @@ var COMPANION_PLUGIN_KEY = "codex@openai-codex";
109156
109893
  var DEFAULT_PLUGIN_VERSION = "0.1.0";
109157
109894
  var COMPANION_LIFECYCLE_EVENTS = new Set(["session_start", "stop"]);
109158
109895
  var CODEX_BIN_NAMES = [
109159
- "omo",
109896
+ "omo-agent-toolkit",
109160
109897
  "omo-rules",
109161
109898
  "omo-lsp",
109162
109899
  "omo-comment-checker",
@@ -109166,13 +109903,13 @@ var CODEX_BIN_NAMES = [
109166
109903
  "omo-git-bash-hook"
109167
109904
  ];
109168
109905
  async function gatherCodexSummary(deps = {}) {
109169
- const codexHome = resolve20(deps.codexHome ?? process.env.CODEX_HOME ?? join79(homedir19(), ".codex"));
109906
+ const codexHome = resolve22(deps.codexHome ?? process.env.CODEX_HOME ?? join82(homedir20(), ".codex"));
109170
109907
  const binDir = resolveCodexInstallerBinDir({ binDir: deps.binDir, codexHome, env: process.env });
109171
109908
  const detection = await (deps.detectCodexInstallation ?? detectCodexInstallation)();
109172
109909
  const pluginRoot = await resolveInstalledPluginRoot(codexHome);
109173
- const manifest2 = pluginRoot === null ? null : await readJson(join79(pluginRoot, ".codex-plugin", "plugin.json"));
109174
- const installSnapshot = pluginRoot === null ? null : await readJson(join79(pluginRoot, "lazycodex-install.json"));
109175
- const configPath = join79(codexHome, "config.toml");
109910
+ const manifest2 = pluginRoot === null ? null : await readJson(join82(pluginRoot, ".codex-plugin", "plugin.json"));
109911
+ const installSnapshot = pluginRoot === null ? null : await readJson(join82(pluginRoot, "lazycodex-install.json"));
109912
+ const configPath = join82(codexHome, "config.toml");
109176
109913
  const pluginVersion = stringField(manifest2, "version");
109177
109914
  return {
109178
109915
  codexPath: detection.found && "path" in detection ? detection.path : null,
@@ -109229,7 +109966,7 @@ function buildCodexIssues(summary) {
109229
109966
  if (summary.pluginRoot === null) {
109230
109967
  issues.push({
109231
109968
  title: "OMO Codex plugin is not installed",
109232
- description: `Expected cached plugin at ${join79("plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2, DEFAULT_PLUGIN_VERSION)} under CODEX_HOME.`,
109969
+ description: `Expected cached plugin at ${join82("plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2, DEFAULT_PLUGIN_VERSION)} under CODEX_HOME.`,
109233
109970
  fix: "Run: npx lazycodex-ai install",
109234
109971
  severity: "error",
109235
109972
  affects: ["plugin loading"]
@@ -109243,10 +109980,10 @@ function buildCodexIssues(summary) {
109243
109980
  affects: ["version reporting"]
109244
109981
  });
109245
109982
  }
109246
- if (summary.pluginRoot !== null && !summary.linkedBins.includes("omo")) {
109983
+ if (summary.pluginRoot !== null && !summary.linkedBins.includes("omo-agent-toolkit")) {
109247
109984
  issues.push({
109248
- title: "omo runtime command is not linked",
109249
- description: "The omo runtime wrapper is missing from the installer bin directory, so `omo ulw-loop` fails in Codex sessions. lazycodex-ai 4.8.0/4.8.1 installs removed the legacy omo bin without writing a replacement.",
109985
+ title: "omo-agent-toolkit runtime command is not linked",
109986
+ description: "The omo-agent-toolkit runtime wrapper is missing from the installer bin directory, so `omo-agent-toolkit ulw-loop` fails in Codex sessions. Reinstall LazyCodex to write the canonical wrapper.",
109250
109987
  fix: "Run: npx lazycodex-ai@latest install",
109251
109988
  severity: "error",
109252
109989
  affects: ["ulw-loop"]
@@ -109294,15 +110031,15 @@ function buildCodexIssues(summary) {
109294
110031
  return issues;
109295
110032
  }
109296
110033
  async function resolveInstalledPluginRoot(codexHome) {
109297
- const pluginRoot = join79(codexHome, "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2);
109298
- if (!existsSync56(pluginRoot))
110034
+ const pluginRoot = join82(codexHome, "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2);
110035
+ if (!existsSync57(pluginRoot))
109299
110036
  return null;
109300
- const versions2 = await readdir12(pluginRoot, { withFileTypes: true });
110037
+ const versions2 = await readdir14(pluginRoot, { withFileTypes: true });
109301
110038
  const candidates = versions2.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionsDescending);
109302
- return candidates.length === 0 ? null : join79(pluginRoot, candidates[0] ?? DEFAULT_PLUGIN_VERSION);
110039
+ return candidates.length === 0 ? null : join82(pluginRoot, candidates[0] ?? DEFAULT_PLUGIN_VERSION);
109303
110040
  }
109304
110041
  async function readCodexConfigSummary(configPath) {
109305
- if (!existsSync56(configPath)) {
110042
+ if (!existsSync57(configPath)) {
109306
110043
  return {
109307
110044
  exists: false,
109308
110045
  marketplaceConfigured: false,
@@ -109313,7 +110050,7 @@ async function readCodexConfigSummary(configPath) {
109313
110050
  companionLifecycleHookStateEvents: []
109314
110051
  };
109315
110052
  }
109316
- const content = await readFile24(configPath, "utf8");
110053
+ const content = await readFile27(configPath, "utf8");
109317
110054
  return {
109318
110055
  exists: true,
109319
110056
  marketplaceConfigured: content.includes("[marketplaces.sisyphuslabs]"),
@@ -109327,21 +110064,21 @@ async function readCodexConfigSummary(configPath) {
109327
110064
  async function readLinkedBins(binDir) {
109328
110065
  const linked = [];
109329
110066
  for (const name of CODEX_BIN_NAMES) {
109330
- if (await pathExists2(join79(binDir, process.platform === "win32" ? `${name}.cmd` : name)))
110067
+ if (await pathExists2(join82(binDir, process.platform === "win32" ? `${name}.cmd` : name)))
109331
110068
  linked.push(name);
109332
110069
  }
109333
110070
  return linked;
109334
110071
  }
109335
110072
  async function readLinkedAgents(codexHome) {
109336
- const agentsDir = join79(codexHome, "agents");
109337
- if (!existsSync56(agentsDir))
110073
+ const agentsDir = join82(codexHome, "agents");
110074
+ if (!existsSync57(agentsDir))
109338
110075
  return [];
109339
- const entries = await readdir12(agentsDir, { withFileTypes: true });
110076
+ const entries = await readdir14(agentsDir, { withFileTypes: true });
109340
110077
  return entries.filter((entry) => entry.isFile() || entry.isSymbolicLink()).map((entry) => basename11(entry.name, ".toml")).sort();
109341
110078
  }
109342
110079
  async function readJson(path14) {
109343
110080
  try {
109344
- const parsed = JSON.parse(await readFile24(path14, "utf8"));
110081
+ const parsed = JSON.parse(await readFile27(path14, "utf8"));
109345
110082
  return isPlainRecord(parsed) ? parsed : null;
109346
110083
  } catch (error51) {
109347
110084
  if (error51 instanceof Error)
@@ -109436,7 +110173,7 @@ function compareVersionsDescending(left, right) {
109436
110173
  }
109437
110174
  async function pathExists2(path14) {
109438
110175
  try {
109439
- await lstat14(path14);
110176
+ await lstat15(path14);
109440
110177
  return true;
109441
110178
  } catch (error51) {
109442
110179
  if (error51 instanceof Error)
@@ -109447,9 +110184,9 @@ async function pathExists2(path14) {
109447
110184
 
109448
110185
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
109449
110186
  init_src2();
109450
- import { readdir as readdir13, readFile as readFile25, stat as stat6 } from "fs/promises";
109451
- import { homedir as homedir20 } from "os";
109452
- import { dirname as dirname29, isAbsolute as isAbsolute11, join as join80, relative as relative9, resolve as resolve21, sep as sep9 } from "path";
110187
+ import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "fs/promises";
110188
+ import { homedir as homedir21 } from "os";
110189
+ import { dirname as dirname31, isAbsolute as isAbsolute12, join as join83, relative as relative9, resolve as resolve23, sep as sep9 } from "path";
109453
110190
  var CODEX_COMPONENTS_CHECK_ID = "codex-components";
109454
110191
  var CODEX_COMPONENTS_CHECK_NAME = "codex-components";
109455
110192
  var PLUGIN_DATA_DIR_NAME = "omo-sisyphuslabs";
@@ -109459,7 +110196,7 @@ async function checkCodexComponents(deps = {}) {
109459
110196
  const env3 = deps.env ?? process.env;
109460
110197
  const platform = deps.platform ?? process.platform;
109461
110198
  const arch = deps.arch ?? process.arch;
109462
- const codexHome = resolve21(deps.codexHome ?? env3["CODEX_HOME"] ?? join80(homedir20(), ".codex"));
110199
+ const codexHome = resolve23(deps.codexHome ?? env3["CODEX_HOME"] ?? join83(homedir21(), ".codex"));
109463
110200
  const summary = await gatherCodexSummary({ ...deps, codexHome });
109464
110201
  if (summary.pluginRoot === null) {
109465
110202
  return {
@@ -109484,7 +110221,7 @@ async function checkCodexComponents(deps = {}) {
109484
110221
  });
109485
110222
  }
109486
110223
  const runtimeSgDir = runtimeSgDirectory(codexHome, platform, arch);
109487
- const runtimeSgPath = join80(runtimeSgDir, sgBinaryName(platform));
110224
+ const runtimeSgPath = join83(runtimeSgDir, sgBinaryName(platform));
109488
110225
  const sg = findSgBinarySync({
109489
110226
  arch,
109490
110227
  env: env3,
@@ -109521,12 +110258,12 @@ async function auditBundleTargets(pluginRoot) {
109521
110258
  let referencedCount = 0;
109522
110259
  for (const manifestPath of await findManifestPaths(pluginRoot, ".mcp.json")) {
109523
110260
  const manifest2 = await readJson2(manifestPath);
109524
- if (manifest2 === null || !isRecord11(manifest2["mcpServers"]))
110261
+ if (manifest2 === null || !isRecord12(manifest2["mcpServers"]))
109525
110262
  continue;
109526
- const manifestRoot = dirname29(manifestPath);
109527
- const isRootManifest = resolve21(manifestRoot) === resolve21(pluginRoot);
110263
+ const manifestRoot = dirname31(manifestPath);
110264
+ const isRootManifest = resolve23(manifestRoot) === resolve23(pluginRoot);
109528
110265
  for (const server2 of Object.values(manifest2["mcpServers"])) {
109529
- if (!isRecord11(server2) || !Array.isArray(server2["args"]))
110266
+ if (!isRecord12(server2) || !Array.isArray(server2["args"]))
109530
110267
  continue;
109531
110268
  for (const arg of server2["args"]) {
109532
110269
  if (typeof arg !== "string" || !isPluginRuntimePathArg(arg))
@@ -109544,7 +110281,7 @@ async function auditBundleTargets(pluginRoot) {
109544
110281
  continue;
109545
110282
  const commands2 = [];
109546
110283
  collectHookCommands(manifest2, commands2);
109547
- const hookPluginRoot = dirname29(dirname29(hookManifestPath));
110284
+ const hookPluginRoot = dirname31(dirname31(hookManifestPath));
109548
110285
  for (const command of commands2) {
109549
110286
  for (const relativePath of extractPluginRootPaths(command)) {
109550
110287
  referencedCount += 1;
@@ -109566,8 +110303,8 @@ function recordBrokenTarget(broken, classified, origin) {
109566
110303
  broken.push(entry);
109567
110304
  }
109568
110305
  async function classifyBundleTarget(bundleRoot, baseRoot, relativePath, allowEscape) {
109569
- const targetPath = resolve21(baseRoot, relativePath);
109570
- const bundleRootPath = resolve21(bundleRoot);
110306
+ const targetPath = resolve23(baseRoot, relativePath);
110307
+ const bundleRootPath = resolve23(bundleRoot);
109571
110308
  const bundleRootPrefix = bundleRootPath.endsWith(sep9) ? bundleRootPath : `${bundleRootPath}${sep9}`;
109572
110309
  if (targetPath !== bundleRootPath && !targetPath.startsWith(bundleRootPrefix)) {
109573
110310
  if (allowEscape)
@@ -109583,12 +110320,12 @@ async function classifyBundleTarget(bundleRoot, baseRoot, relativePath, allowEsc
109583
110320
  }
109584
110321
  async function findHookManifestPaths(root) {
109585
110322
  const paths3 = await findManifestPaths(root, "hooks.json");
109586
- return paths3.filter((path14) => dirname29(path14).endsWith(`${sep9}hooks`));
110323
+ return paths3.filter((path14) => dirname31(path14).endsWith(`${sep9}hooks`));
109587
110324
  }
109588
110325
  async function findManifestPaths(root, manifestName) {
109589
110326
  let entries;
109590
110327
  try {
109591
- entries = await readdir13(root, { withFileTypes: true });
110328
+ entries = await readdir15(root, { withFileTypes: true });
109592
110329
  } catch {
109593
110330
  return [];
109594
110331
  }
@@ -109596,7 +110333,7 @@ async function findManifestPaths(root, manifestName) {
109596
110333
  for (const entry of entries) {
109597
110334
  if (entry.name === "node_modules" || entry.name === ".git")
109598
110335
  continue;
109599
- const entryPath = join80(root, entry.name);
110336
+ const entryPath = join83(root, entry.name);
109600
110337
  if (entry.isDirectory()) {
109601
110338
  paths3.push(...await findManifestPaths(entryPath, manifestName));
109602
110339
  continue;
@@ -109612,7 +110349,7 @@ function collectHookCommands(value, commands2) {
109612
110349
  collectHookCommands(item, commands2);
109613
110350
  return;
109614
110351
  }
109615
- if (!isRecord11(value))
110352
+ if (!isRecord12(value))
109616
110353
  return;
109617
110354
  if (value["type"] === "command") {
109618
110355
  if (typeof value["command"] === "string")
@@ -109637,21 +110374,21 @@ function extractPluginRootPaths(command) {
109637
110374
  }
109638
110375
  function isPluginRuntimePathArg(arg) {
109639
110376
  const normalized = normalizePathSeparators(arg);
109640
- return normalized.endsWith(".js") && normalized.includes("/dist/") && (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("components/") || normalized.startsWith("/") || isAbsolute11(arg));
110377
+ return normalized.endsWith(".js") && normalized.includes("/dist/") && (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("components/") || normalized.startsWith("/") || isAbsolute12(arg));
109641
110378
  }
109642
110379
  function runtimeSgDirectory(codexHome, platform, arch) {
109643
- return join80(codexHome, "runtime", "ast-grep", runtimeSlug(platform, arch));
110380
+ return join83(codexHome, "runtime", "ast-grep", runtimeSlug(platform, arch));
109644
110381
  }
109645
110382
  function describeSgSource(sgPath, env3, runtimeSgDir, platform) {
109646
110383
  const override = env3[SG_PATH_ENV_KEY]?.trim();
109647
110384
  if (override !== undefined && override.length > 0 && sgPath === override)
109648
110385
  return `env override ${SG_PATH_ENV_KEY}`;
109649
- if (sgPath === join80(runtimeSgDir, sgBinaryName(platform)))
110386
+ if (sgPath === join83(runtimeSgDir, sgBinaryName(platform)))
109650
110387
  return "runtime dir";
109651
110388
  return "PATH";
109652
110389
  }
109653
110390
  async function readBootstrapStateSummary(codexHome) {
109654
- const statePath = join80(codexHome, "plugins", "data", PLUGIN_DATA_DIR_NAME, "bootstrap", "state.json");
110391
+ const statePath = join83(codexHome, "plugins", "data", PLUGIN_DATA_DIR_NAME, "bootstrap", "state.json");
109655
110392
  const raw = await readJson2(statePath);
109656
110393
  if (raw === null)
109657
110394
  return null;
@@ -109667,7 +110404,7 @@ function parseDegradedEntries(value) {
109667
110404
  return [];
109668
110405
  const entries = [];
109669
110406
  for (const item of value) {
109670
- if (!isRecord11(item))
110407
+ if (!isRecord12(item))
109671
110408
  continue;
109672
110409
  if (typeof item["component"] !== "string" || typeof item["reason"] !== "string")
109673
110410
  continue;
@@ -109700,8 +110437,8 @@ function degradedDetailLines(entries) {
109700
110437
  }
109701
110438
  async function readJson2(path14) {
109702
110439
  try {
109703
- const parsed = JSON.parse(await readFile25(path14, "utf8"));
109704
- return isRecord11(parsed) ? parsed : null;
110440
+ const parsed = JSON.parse(await readFile28(path14, "utf8"));
110441
+ return isRecord12(parsed) ? parsed : null;
109705
110442
  } catch (error51) {
109706
110443
  if (error51 instanceof Error)
109707
110444
  return null;
@@ -109710,7 +110447,7 @@ async function readJson2(path14) {
109710
110447
  }
109711
110448
  async function fileSize(path14) {
109712
110449
  try {
109713
- const stats = await stat6(path14);
110450
+ const stats = await stat7(path14);
109714
110451
  return stats.isFile() ? stats.size : undefined;
109715
110452
  } catch {
109716
110453
  return;
@@ -109722,37 +110459,47 @@ function normalizeRelative(root, target) {
109722
110459
  function normalizePathSeparators(path14) {
109723
110460
  return path14.split("\\").join("/");
109724
110461
  }
109725
- function isRecord11(value) {
110462
+ function isRecord12(value) {
109726
110463
  return typeof value === "object" && value !== null && !Array.isArray(value);
109727
110464
  }
109728
110465
 
109729
110466
  // packages/omo-opencode/src/cli/doctor/checks/codex-runtime-wrapper.ts
109730
- import { existsSync as existsSync57 } from "fs";
109731
- import { readFile as readFile26 } from "fs/promises";
109732
- import { homedir as homedir21 } from "os";
109733
- import { join as join81, resolve as resolve22 } from "path";
110467
+ import { existsSync as existsSync58 } from "fs";
110468
+ import { readFile as readFile29 } from "fs/promises";
110469
+ import { homedir as homedir22 } from "os";
110470
+ import { join as join84, resolve as resolve24 } from "path";
109734
110471
  var RUNTIME_WRAPPER_MARKER2 = "OMO_GENERATED_RUNTIME_WRAPPER";
109735
110472
  var CHECK_NAME = "codex-runtime-wrapper";
109736
110473
  var REINSTALL_COMMAND = "npx --yes lazycodex-ai@latest install --no-tui";
109737
110474
  async function checkCodexRuntimeWrapper(deps = {}) {
109738
- const codexHome = resolve22(deps.codexHome ?? process.env.CODEX_HOME ?? join81(homedir21(), ".codex"));
110475
+ const codexHome = resolve24(deps.codexHome ?? process.env.CODEX_HOME ?? join84(homedir22(), ".codex"));
109739
110476
  const binDir = resolveCodexInstallerBinDir({ binDir: deps.binDir, codexHome, env: process.env });
109740
110477
  const platform = deps.platform ?? process.platform;
109741
- const wrapperPath = join81(binDir, platform === "win32" ? "omo.cmd" : "omo");
109742
- const wrapper = await readRuntimeWrapper(wrapperPath);
110478
+ const wrapperPath = join84(binDir, platform === "win32" ? "omo-agent-toolkit.cmd" : "omo-agent-toolkit");
110479
+ const legacyWrapperPath = join84(binDir, platform === "win32" ? "omo.cmd" : "omo");
110480
+ const [wrapper, legacyWrapper] = await Promise.all([readRuntimeWrapper(wrapperPath), readRuntimeWrapper(legacyWrapperPath)]);
109743
110481
  const issues = [];
109744
110482
  if (wrapper?.includes(RUNTIME_WRAPPER_MARKER2) === true) {
109745
110483
  const targetPath = parseRuntimeTargetPath(wrapper);
109746
- if (targetPath !== null && !existsSync57(targetPath)) {
110484
+ if (targetPath !== null && !existsSync58(targetPath)) {
109747
110485
  issues.push({
109748
- title: "omo runtime wrapper target is missing",
109749
- description: `Generated omo runtime wrapper at ${wrapperPath} points to missing target ${targetPath}.`,
110486
+ title: "omo-agent-toolkit runtime wrapper target is missing",
110487
+ description: `Generated omo-agent-toolkit runtime wrapper at ${wrapperPath} points to missing target ${targetPath}.`,
109750
110488
  fix: `Run: ${REINSTALL_COMMAND}`,
109751
110489
  severity: "warning",
109752
110490
  affects: ["ulw-loop"]
109753
110491
  });
109754
110492
  }
109755
110493
  }
110494
+ if (legacyWrapper?.includes(RUNTIME_WRAPPER_MARKER2) === true) {
110495
+ issues.push({
110496
+ title: "Legacy omo runtime wrapper is still installed",
110497
+ description: `Generated legacy omo runtime wrapper remains at ${legacyWrapperPath} and may execute an outdated cached CLI.`,
110498
+ fix: `Run: ${REINSTALL_COMMAND}`,
110499
+ severity: "warning",
110500
+ affects: ["version routing"]
110501
+ });
110502
+ }
109756
110503
  return {
109757
110504
  name: CHECK_NAME,
109758
110505
  status: issues.length > 0 ? "warn" : "pass",
@@ -109763,7 +110510,7 @@ async function checkCodexRuntimeWrapper(deps = {}) {
109763
110510
  }
109764
110511
  async function readRuntimeWrapper(path14) {
109765
110512
  try {
109766
- return await readFile26(path14, "utf8");
110513
+ return await readFile29(path14, "utf8");
109767
110514
  } catch (error51) {
109768
110515
  if (error51 instanceof Error)
109769
110516
  return null;
@@ -110216,6 +110963,8 @@ init_shared();
110216
110963
  function resolveDoctorTarget(invocationName, platform) {
110217
110964
  if (platform !== undefined)
110218
110965
  return platform;
110966
+ if (process.env.OMO_EDITION === "codex")
110967
+ return "codex";
110219
110968
  return invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : "opencode";
110220
110969
  }
110221
110970
 
@@ -110244,10 +110993,10 @@ Doctor failed unexpectedly: ${message}`];
110244
110993
  }
110245
110994
 
110246
110995
  // packages/mcp-client-core/src/mcp-oauth/storage.ts
110247
- import { createHash as createHash5 } from "crypto";
110996
+ import { createHash as createHash6 } from "crypto";
110248
110997
  import {
110249
110998
  chmodSync as chmodSync4,
110250
- existsSync as existsSync60,
110999
+ existsSync as existsSync61,
110251
111000
  mkdirSync as mkdirSync14,
110252
111001
  readdirSync as readdirSync11,
110253
111002
  readFileSync as readFileSync38,
@@ -110255,15 +111004,15 @@ import {
110255
111004
  unlinkSync as unlinkSync9,
110256
111005
  writeFileSync as writeFileSync11
110257
111006
  } from "fs";
110258
- import { basename as basename12, dirname as dirname30, join as join84 } from "path";
111007
+ import { basename as basename12, dirname as dirname32, join as join87 } from "path";
110259
111008
 
110260
111009
  // packages/mcp-client-core/src/config-dir.ts
110261
- import { existsSync as existsSync58, realpathSync as realpathSync8 } from "fs";
110262
- import { homedir as homedir22 } from "os";
110263
- import { join as join82, resolve as resolve23 } from "path";
111010
+ import { existsSync as existsSync59, realpathSync as realpathSync8 } from "fs";
111011
+ import { homedir as homedir23 } from "os";
111012
+ import { join as join85, resolve as resolve25 } from "path";
110264
111013
  function resolveConfigPath2(pathValue) {
110265
- const resolvedPath = resolve23(pathValue);
110266
- if (!existsSync58(resolvedPath))
111014
+ const resolvedPath = resolve25(pathValue);
111015
+ if (!existsSync59(resolvedPath))
110267
111016
  return resolvedPath;
110268
111017
  try {
110269
111018
  return realpathSync8(resolvedPath);
@@ -110278,13 +111027,13 @@ function getOpenCodeCliConfigDir(env3 = process.env) {
110278
111027
  if (customConfigDir) {
110279
111028
  return resolveConfigPath2(customConfigDir);
110280
111029
  }
110281
- const xdgConfigDir = env3["XDG_CONFIG_HOME"]?.trim() || join82(homedir22(), ".config");
110282
- return resolveConfigPath2(join82(xdgConfigDir, "opencode"));
111030
+ const xdgConfigDir = env3["XDG_CONFIG_HOME"]?.trim() || join85(homedir23(), ".config");
111031
+ return resolveConfigPath2(join85(xdgConfigDir, "opencode"));
110283
111032
  }
110284
111033
 
110285
111034
  // packages/mcp-client-core/src/mcp-oauth/storage-index.ts
110286
- import { chmodSync as chmodSync3, existsSync as existsSync59, readFileSync as readFileSync37, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "fs";
110287
- import { join as join83 } from "path";
111035
+ import { chmodSync as chmodSync3, existsSync as existsSync60, readFileSync as readFileSync37, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "fs";
111036
+ import { join as join86 } from "path";
110288
111037
  var INDEX_FILE_NAME = "index.json";
110289
111038
  function isTokenIndex(value) {
110290
111039
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -110292,11 +111041,11 @@ function isTokenIndex(value) {
110292
111041
  return Object.values(value).every((entry) => typeof entry === "string");
110293
111042
  }
110294
111043
  function getIndexPath(storageDir) {
110295
- return join83(storageDir, INDEX_FILE_NAME);
111044
+ return join86(storageDir, INDEX_FILE_NAME);
110296
111045
  }
110297
111046
  function readTokenIndex(storageDir) {
110298
111047
  const indexPath = getIndexPath(storageDir);
110299
- if (!existsSync59(indexPath))
111048
+ if (!existsSync60(indexPath))
110300
111049
  return {};
110301
111050
  try {
110302
111051
  const parsed = JSON.parse(readFileSync37(indexPath, "utf-8"));
@@ -110336,16 +111085,16 @@ function deleteTokenIndexEntry(storageDir, hash2) {
110336
111085
  var STORAGE_DIR_NAME = "mcp-oauth";
110337
111086
  var LEGACY_STORAGE_FILE_NAME = "mcp-oauth.json";
110338
111087
  function getMcpOauthStorageDir() {
110339
- return join84(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
111088
+ return join87(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
110340
111089
  }
110341
111090
  function getMcpOauthServerHash(serverHost, resource) {
110342
- return createHash5("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
111091
+ return createHash6("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
110343
111092
  }
110344
111093
  function getMcpOauthStoragePath(serverHost, resource) {
110345
- return join84(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
111094
+ return join87(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
110346
111095
  }
110347
111096
  function getLegacyStoragePath() {
110348
- return join84(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
111097
+ return join87(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
110349
111098
  }
110350
111099
  function normalizeHost2(serverHost) {
110351
111100
  let host = serverHost.trim();
@@ -110406,7 +111155,7 @@ function isOAuthTokenData(value) {
110406
111155
  return clientSecret === undefined || typeof clientSecret === "string";
110407
111156
  }
110408
111157
  function readTokenFile(filePath) {
110409
- if (!existsSync60(filePath))
111158
+ if (!existsSync61(filePath))
110410
111159
  return null;
110411
111160
  try {
110412
111161
  const parsed = JSON.parse(readFileSync38(filePath, "utf-8"));
@@ -110419,7 +111168,7 @@ function readTokenFile(filePath) {
110419
111168
  }
110420
111169
  function readLegacyStore() {
110421
111170
  const filePath = getLegacyStoragePath();
110422
- if (!existsSync60(filePath))
111171
+ if (!existsSync61(filePath))
110423
111172
  return null;
110424
111173
  try {
110425
111174
  const parsed = JSON.parse(readFileSync38(filePath, "utf-8"));
@@ -110439,8 +111188,8 @@ function readLegacyStore() {
110439
111188
  }
110440
111189
  function writeTokenFile(filePath, token) {
110441
111190
  try {
110442
- const dir = dirname30(filePath);
110443
- if (!existsSync60(dir)) {
111191
+ const dir = dirname32(filePath);
111192
+ if (!existsSync61(dir)) {
110444
111193
  mkdirSync14(dir, { recursive: true });
110445
111194
  }
110446
111195
  const tempPath = `${filePath}.tmp.${Date.now()}`;
@@ -110464,7 +111213,7 @@ function saveToken(serverHost, resource, token) {
110464
111213
  }
110465
111214
  function deleteToken(serverHost, resource) {
110466
111215
  const filePath = getMcpOauthStoragePath(serverHost, resource);
110467
- if (!existsSync60(filePath))
111216
+ if (!existsSync61(filePath))
110468
111217
  return deleteLegacyToken(serverHost, resource);
110469
111218
  try {
110470
111219
  unlinkSync9(filePath);
@@ -110486,7 +111235,7 @@ function deleteLegacyToken(serverHost, resource) {
110486
111235
  if (Object.keys(store2).length === 0) {
110487
111236
  try {
110488
111237
  const filePath = getLegacyStoragePath();
110489
- if (existsSync60(filePath))
111238
+ if (existsSync61(filePath))
110490
111239
  unlinkSync9(filePath);
110491
111240
  return true;
110492
111241
  } catch (deleteError) {
@@ -110524,7 +111273,7 @@ function listTokensByHost(serverHost) {
110524
111273
  for (const [hash2, indexedKey] of Object.entries(index)) {
110525
111274
  if (!indexedKey.startsWith(prefix))
110526
111275
  continue;
110527
- const indexedToken = readTokenFile(join84(getMcpOauthStorageDir(), `${hash2}.json`));
111276
+ const indexedToken = readTokenFile(join87(getMcpOauthStorageDir(), `${hash2}.json`));
110528
111277
  if (indexedToken)
110529
111278
  result[indexedKey] = indexedToken;
110530
111279
  }
@@ -110533,13 +111282,13 @@ function listTokensByHost(serverHost) {
110533
111282
  function listAllTokens() {
110534
111283
  const result = { ...readLegacyStore() ?? {} };
110535
111284
  const dir = getMcpOauthStorageDir();
110536
- if (!existsSync60(dir))
111285
+ if (!existsSync61(dir))
110537
111286
  return result;
110538
111287
  const index = readTokenIndex(dir);
110539
111288
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
110540
111289
  if (!entry.isFile() || !entry.name.endsWith(".json") || entry.name === "index.json")
110541
111290
  continue;
110542
- const token = readTokenFile(join84(dir, entry.name));
111291
+ const token = readTokenFile(join87(dir, entry.name));
110543
111292
  const hash2 = basename12(entry.name, ".json");
110544
111293
  if (token)
110545
111294
  result[index[hash2] ?? hash2] = token;
@@ -110713,13 +111462,13 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
110713
111462
 
110714
111463
  // packages/mcp-client-core/src/mcp-oauth/oauth-authorization-flow.ts
110715
111464
  import { spawn as spawn4 } from "child_process";
110716
- import { createHash as createHash6, randomBytes as randomBytes2 } from "crypto";
111465
+ import { createHash as createHash7, randomBytes as randomBytes2 } from "crypto";
110717
111466
  import { createServer as createServer2 } from "http";
110718
111467
  function generateCodeVerifier() {
110719
111468
  return randomBytes2(32).toString("base64url");
110720
111469
  }
110721
111470
  function generateCodeChallenge(verifier) {
110722
- return createHash6("sha256").update(verifier).digest("base64url");
111471
+ return createHash7("sha256").update(verifier).digest("base64url");
110723
111472
  }
110724
111473
  function buildAuthorizationUrl(authorizationEndpoint, options) {
110725
111474
  const url2 = new URL(authorizationEndpoint);
@@ -110739,7 +111488,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
110739
111488
  }
110740
111489
  var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
110741
111490
  function startCallbackServer(port) {
110742
- return new Promise((resolve24, reject) => {
111491
+ return new Promise((resolve26, reject) => {
110743
111492
  let timeoutId;
110744
111493
  const server2 = createServer2((request, response) => {
110745
111494
  clearTimeout(timeoutId);
@@ -110765,7 +111514,7 @@ function startCallbackServer(port) {
110765
111514
  response.writeHead(200, { "content-type": "text/html" });
110766
111515
  response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
110767
111516
  server2.close();
110768
- resolve24({ code, state: state2 });
111517
+ resolve26({ code, state: state2 });
110769
111518
  });
110770
111519
  timeoutId = setTimeout(() => {
110771
111520
  server2.close();
@@ -111105,7 +111854,7 @@ function createMcpOAuthCommand() {
111105
111854
  }
111106
111855
 
111107
111856
  // packages/omo-opencode/src/cli/boulder/boulder.ts
111108
- import { existsSync as existsSync61 } from "fs";
111857
+ import { existsSync as existsSync62 } from "fs";
111109
111858
 
111110
111859
  // packages/omo-opencode/src/cli/boulder/formatter.ts
111111
111860
  var import_picocolors22 = __toESM(require_picocolors(), 1);
@@ -111242,10 +111991,10 @@ async function boulder(options) {
111242
111991
  const boulderFilePath = getBoulderFilePath(directory);
111243
111992
  const state2 = readBoulderState(directory);
111244
111993
  if (!state2) {
111245
- const message = existsSync61(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
111994
+ const message = existsSync62(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
111246
111995
  process.stderr.write(`${message}
111247
111996
  `);
111248
- return existsSync61(boulderFilePath) ? 2 : 1;
111997
+ return existsSync62(boulderFilePath) ? 2 : 1;
111249
111998
  }
111250
111999
  const works = getBoulderWorks(state2);
111251
112000
  const filteredWorks = options.workId ? works.filter((work) => work.work_id === options.workId) : works;
@@ -111263,12 +112012,12 @@ async function boulder(options) {
111263
112012
  }
111264
112013
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
111265
112014
  import { spawn as spawn5 } from "child_process";
111266
- import { existsSync as existsSync62, readFileSync as readFileSync39, realpathSync as realpathSync9 } from "fs";
111267
- import { homedir as homedir23 } from "os";
112015
+ import { existsSync as existsSync63, readFileSync as readFileSync39, realpathSync as realpathSync9 } from "fs";
112016
+ import { homedir as homedir24 } from "os";
111268
112017
  var ULW_LOOP_DELEGATION_SENTINEL = "OMO_ULW_LOOP_DELEGATED";
111269
112018
  function resolveCodexUlwLoopCommand(input = {}) {
111270
112019
  const env3 = input.env ?? process.env;
111271
- const homeDir = input.homeDir ?? homedir23();
112020
+ const homeDir = input.homeDir ?? homedir24();
111272
112021
  const localComponentBin = resolveLocalUlwLoopBin(env3, homeDir);
111273
112022
  if (localComponentBin !== null)
111274
112023
  return { executable: localComponentBin, argsPrefix: [] };
@@ -111291,37 +112040,37 @@ async function codexUlwLoop(args) {
111291
112040
  console.error("Codex ulw-loop is not installed. Run: npx lazycodex-ai@latest install --no-tui");
111292
112041
  return 1;
111293
112042
  }
111294
- const { promise: promise2, resolve: resolve24 } = Promise.withResolvers();
112043
+ const { promise: promise2, resolve: resolve26 } = Promise.withResolvers();
111295
112044
  const child = spawn5(command.executable, [...command.argsPrefix, ...args], {
111296
112045
  stdio: "inherit",
111297
112046
  env: { ...process.env, [ULW_LOOP_DELEGATION_SENTINEL]: "1" }
111298
112047
  });
111299
112048
  child.on("error", (error51) => {
111300
112049
  console.error(error51.message);
111301
- resolve24(1);
112050
+ resolve26(1);
111302
112051
  });
111303
- child.on("close", (code) => resolve24(code ?? 1));
112052
+ child.on("close", (code) => resolve26(code ?? 1));
111304
112053
  return promise2;
111305
112054
  }
111306
112055
  function resolveLocalUlwLoopBin(env3, homeDir) {
111307
112056
  const candidates = resolveCodexComponentBinCandidates({ executableName: "omo-ulw-loop", env: env3, homeDir });
111308
- return candidates.find((candidate) => existsSync62(candidate)) ?? null;
112057
+ return candidates.find((candidate2) => existsSync63(candidate2)) ?? null;
111309
112058
  }
111310
112059
  function resolveLegacyLocalOmoBin(env3, homeDir, currentExecutablePaths) {
111311
112060
  const candidates = resolveCodexComponentBinCandidates({ executableName: "omo", env: env3, homeDir });
111312
- return candidates.find((candidate) => existsSync62(candidate) && !isCurrentExecutable(candidate, currentExecutablePaths) && !isGeneratedRuntimeWrapper(candidate)) ?? null;
112061
+ return candidates.find((candidate2) => existsSync63(candidate2) && !isCurrentExecutable(candidate2, currentExecutablePaths) && !isGeneratedRuntimeWrapper(candidate2)) ?? null;
111313
112062
  }
111314
- function isGeneratedRuntimeWrapper(candidate) {
112063
+ function isGeneratedRuntimeWrapper(candidate2) {
111315
112064
  try {
111316
- return readFileSync39(candidate, "utf8").includes(RUNTIME_WRAPPER_MARKER);
112065
+ return readFileSync39(candidate2, "utf8").includes(RUNTIME_WRAPPER_MARKER);
111317
112066
  } catch (error51) {
111318
112067
  if (error51 instanceof Error)
111319
112068
  return false;
111320
112069
  return false;
111321
112070
  }
111322
112071
  }
111323
- function isCurrentExecutable(candidate, currentExecutablePaths) {
111324
- const candidateRealPath = realpathOrSelf2(candidate);
112072
+ function isCurrentExecutable(candidate2, currentExecutablePaths) {
112073
+ const candidateRealPath = realpathOrSelf2(candidate2);
111325
112074
  return currentExecutablePaths.some((currentPath) => realpathOrSelf2(currentPath) === candidateRealPath);
111326
112075
  }
111327
112076
  function realpathOrSelf2(path14) {
@@ -111459,7 +112208,7 @@ init_package();
111459
112208
  var VERSION3 = package_default.version;
111460
112209
  var program2 = new Command;
111461
112210
  function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {
111462
- const defaultPlatform = invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
112211
+ const defaultPlatform = process.env.OMO_EDITION === "codex" || invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
111463
112212
  const platform = options.platform ?? defaultPlatform;
111464
112213
  if (platform === "senpi" && !isSenpiPlatformEnabled()) {
111465
112214
  throw new Error(`The senpi install platform is not available in this release. Set ${SENPI_PLATFORM_ENV_FLAG}=1 to enable it from a source checkout.`);
@@ -111489,7 +112238,7 @@ Examples:
111489
112238
  $ bunx oh-my-opencode install
111490
112239
  $ npx lazycodex-ai install --no-tui
111491
112240
  $ bunx oh-my-opencode install --no-tui --platform=both --claude=max20 --openai=yes --gemini=yes --copilot=no
111492
- $ omo install --platform=codex --codex-autonomous
112241
+ $ omo-agent-toolkit install --platform=codex --codex-autonomous
111493
112242
  $ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
111494
112243
 
111495
112244
  Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Bailian > MiniMax > Vercel):
@@ -111581,7 +112330,7 @@ Examples:
111581
112330
  $ bunx oh-my-opencode doctor --status # Compact dashboard
111582
112331
  $ bunx oh-my-opencode doctor --verbose # Deep diagnostics
111583
112332
  $ bunx oh-my-opencode doctor --json # JSON output
111584
- $ omo doctor --platform=codex # Codex/LazyCodex diagnostics only
112333
+ $ omo-agent-toolkit doctor --platform=codex # Codex/LazyCodex diagnostics only
111585
112334
  `).action(async (options) => {
111586
112335
  const rootOptions = program2.opts();
111587
112336
  const rootDoctorPlatform = rootOptions.platform === "opencode" || rootOptions.platform === "codex" ? rootOptions.platform : undefined;