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
@@ -2146,7 +2146,7 @@ var package_default;
2146
2146
  var init_package = __esm(() => {
2147
2147
  package_default = {
2148
2148
  name: "oh-my-opencode",
2149
- version: "4.19.4",
2149
+ version: "5.0.0-beta.2",
2150
2150
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2151
2151
  main: "./dist/index.js",
2152
2152
  types: "dist/index.d.ts",
@@ -2154,6 +2154,7 @@ var init_package = __esm(() => {
2154
2154
  workspaces: [
2155
2155
  "packages/rules-engine",
2156
2156
  "packages/delegate-core",
2157
+ "packages/ast-grep-mcp",
2157
2158
  "packages/git-bash-mcp",
2158
2159
  "packages/mcp-stdio-core",
2159
2160
  "packages/mcp-client-core",
@@ -2168,6 +2169,7 @@ var init_package = __esm(() => {
2168
2169
  "packages/team-core",
2169
2170
  "packages/openclaw-core",
2170
2171
  "packages/boulder-state",
2172
+ "packages/memory-core",
2171
2173
  "packages/telemetry-core",
2172
2174
  "packages/claude-code-compat-core",
2173
2175
  "packages/skills-loader-core",
@@ -2178,12 +2180,13 @@ var init_package = __esm(() => {
2178
2180
  "packages/senpi-task",
2179
2181
  "packages/pi-goal",
2180
2182
  "packages/pi-webfetch",
2181
- "packages/omo-opencode"
2183
+ "packages/omo-opencode",
2184
+ "packages/omo-native"
2182
2185
  ],
2183
2186
  bin: {
2184
2187
  "oh-my-opencode": "bin/oh-my-opencode.js",
2185
2188
  "oh-my-openagent": "bin/oh-my-opencode.js",
2186
- omo: "bin/oh-my-opencode.js",
2189
+ "omo-agent-toolkit": "bin/oh-my-opencode.js",
2187
2190
  lazycodex: "bin/oh-my-opencode.js",
2188
2191
  "lazycodex-ai": "bin/oh-my-opencode.js"
2189
2192
  },
@@ -2255,8 +2258,8 @@ var init_package = __esm(() => {
2255
2258
  "build:codex-install": "bun run script/build-codex-install.ts",
2256
2259
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
2257
2260
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
2258
- "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:senpi-plugin:stage",
2259
- "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",
2261
+ "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:ast-grep-mcp && bun run build:senpi-plugin:stage",
2262
+ "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",
2260
2263
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
2261
2264
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
2262
2265
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
@@ -2265,6 +2268,7 @@ var init_package = __esm(() => {
2265
2268
  "build:all": "bun run build && bun run build:binaries",
2266
2269
  "build:binaries": "bun run script/build-binaries.ts",
2267
2270
  "build:schema": "bun run script/build-schema.ts",
2271
+ "build:omo-native": "bun run script/build-omo-native.ts",
2268
2272
  "build:omo-schema": "bun run script/build-omo-schema.ts",
2269
2273
  "build:model-capabilities": "bun run script/build-model-capabilities.ts",
2270
2274
  clean: "rm -rf dist",
@@ -2274,13 +2278,14 @@ var init_package = __esm(() => {
2274
2278
  prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
2275
2279
  "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",
2276
2280
  typecheck: "tsgo --noEmit && bun run typecheck:script && bun run typecheck:packages",
2277
- "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",
2281
+ "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",
2278
2282
  "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
2279
2283
  test: "bun test",
2280
2284
  "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",
2281
2285
  "test:senpi": "bun run build:senpi-plugin && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && bun test packages/omo-senpi",
2282
2286
  "test:windows-codex": "bun run test:codex",
2283
- "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
2287
+ "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build",
2288
+ "build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build"
2284
2289
  },
2285
2290
  keywords: [
2286
2291
  "opencode",
@@ -2321,7 +2326,9 @@ var init_package = __esm(() => {
2321
2326
  zod: "^4.4.3"
2322
2327
  },
2323
2328
  devDependencies: {
2329
+ "@code-yeongyu/senpi": "2026.8.9-2",
2324
2330
  "@oh-my-opencode/agents-md-core": "workspace:*",
2331
+ "@oh-my-opencode/ast-grep-mcp": "workspace:*",
2325
2332
  "@oh-my-opencode/boulder-state": "workspace:*",
2326
2333
  "@oh-my-opencode/claude-code-compat-core": "workspace:*",
2327
2334
  "@oh-my-opencode/comment-checker-core": "workspace:*",
@@ -2329,6 +2336,7 @@ var init_package = __esm(() => {
2329
2336
  "@oh-my-opencode/git-bash-mcp": "workspace:*",
2330
2337
  "@oh-my-opencode/hashline-core": "workspace:*",
2331
2338
  "@oh-my-opencode/lsp-core": "workspace:*",
2339
+ "@oh-my-opencode/memory-core": "workspace:*",
2332
2340
  "@oh-my-opencode/mcp-client-core": "workspace:*",
2333
2341
  "@oh-my-opencode/mcp-stdio-core": "workspace:*",
2334
2342
  "@oh-my-opencode/model-core": "workspace:*",
@@ -2358,18 +2366,18 @@ var init_package = __esm(() => {
2358
2366
  typescript: "^7.0.2"
2359
2367
  },
2360
2368
  optionalDependencies: {
2361
- "oh-my-opencode-darwin-arm64": "4.19.4",
2362
- "oh-my-opencode-darwin-x64": "4.19.4",
2363
- "oh-my-opencode-darwin-x64-baseline": "4.19.4",
2364
- "oh-my-opencode-linux-arm64": "4.19.4",
2365
- "oh-my-opencode-linux-arm64-musl": "4.19.4",
2366
- "oh-my-opencode-linux-x64": "4.19.4",
2367
- "oh-my-opencode-linux-x64-baseline": "4.19.4",
2368
- "oh-my-opencode-linux-x64-musl": "4.19.4",
2369
- "oh-my-opencode-linux-x64-musl-baseline": "4.19.4",
2370
- "oh-my-opencode-windows-arm64": "4.19.4",
2371
- "oh-my-opencode-windows-x64": "4.19.4",
2372
- "oh-my-opencode-windows-x64-baseline": "4.19.4"
2369
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.2",
2370
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.2",
2371
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.2",
2372
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.2",
2373
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.2",
2374
+ "oh-my-opencode-linux-x64": "5.0.0-beta.2",
2375
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.2",
2376
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.2",
2377
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.2",
2378
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.2",
2379
+ "oh-my-opencode-windows-x64": "5.0.0-beta.2",
2380
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.2"
2373
2381
  },
2374
2382
  overrides: {
2375
2383
  "@earendil-works/pi-agent-core": "0.80.3",
@@ -22396,6 +22404,80 @@ var init_codegraph = __esm(() => {
22396
22404
  }).strict();
22397
22405
  });
22398
22406
 
22407
+ // packages/omo-config-core/src/schema/memory.ts
22408
+ var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
22409
+ var init_memory = __esm(() => {
22410
+ init_zod();
22411
+ OmoMemoryReflectionTriggerSchema = object({
22412
+ step_count: number2().int().nonnegative().default(0),
22413
+ on_compaction: boolean2().default(true)
22414
+ }).strict();
22415
+ OmoMemoryReflectionSchema = object({
22416
+ trigger: OmoMemoryReflectionTriggerSchema.default({ step_count: 0, on_compaction: true }),
22417
+ merge: _enum2(["auto", "integration"]).default("auto"),
22418
+ category: string2().min(1).default("quick"),
22419
+ timeout_minutes: number2().int().positive().default(15),
22420
+ sandbox: _enum2(["auto", "required", "off"]).default("auto")
22421
+ }).strict();
22422
+ OmoMemorySyncSchema = object({
22423
+ remote: string2().min(1).optional(),
22424
+ enabled: boolean2().default(true)
22425
+ }).strict();
22426
+ OmoMemorySearchSchema = object({
22427
+ enabled: boolean2().default(true)
22428
+ }).strict();
22429
+ OmoMemoryReflectionTriggerLayerSchema = object({
22430
+ step_count: number2().int().nonnegative().optional(),
22431
+ on_compaction: boolean2().optional()
22432
+ }).strict();
22433
+ OmoMemoryReflectionLayerSchema = object({
22434
+ trigger: OmoMemoryReflectionTriggerLayerSchema.optional(),
22435
+ merge: _enum2(["auto", "integration"]).optional(),
22436
+ category: string2().min(1).optional(),
22437
+ timeout_minutes: number2().int().positive().optional(),
22438
+ sandbox: _enum2(["auto", "required", "off"]).optional()
22439
+ }).strict();
22440
+ OmoMemorySyncLayerSchema = object({
22441
+ remote: string2().min(1).optional(),
22442
+ enabled: boolean2().optional()
22443
+ }).strict();
22444
+ OmoMemorySearchLayerSchema = object({
22445
+ enabled: boolean2().optional()
22446
+ }).strict();
22447
+ OmoMemoryAgentOverridesSchema = object({
22448
+ enabled: boolean2().optional(),
22449
+ agent: string2().min(1).optional(),
22450
+ reflection: OmoMemoryReflectionLayerSchema.optional(),
22451
+ sync: OmoMemorySyncLayerSchema.optional(),
22452
+ search: OmoMemorySearchLayerSchema.optional(),
22453
+ compile_warn_tokens: number2().int().positive().optional()
22454
+ }).strict();
22455
+ OmoMemorySettingsSchema = object({
22456
+ enabled: boolean2().default(true),
22457
+ agent: string2().min(1).default("auto"),
22458
+ reflection: OmoMemoryReflectionSchema.default({
22459
+ trigger: { step_count: 0, on_compaction: true },
22460
+ merge: "auto",
22461
+ category: "quick",
22462
+ timeout_minutes: 15,
22463
+ sandbox: "auto"
22464
+ }),
22465
+ sync: OmoMemorySyncSchema.default({ enabled: true }),
22466
+ search: OmoMemorySearchSchema.default({ enabled: true }),
22467
+ compile_warn_tokens: number2().int().positive().default(30000),
22468
+ agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
22469
+ }).strict();
22470
+ OmoMemorySettingsLayerSchema = object({
22471
+ enabled: boolean2().optional(),
22472
+ agent: string2().min(1).optional(),
22473
+ reflection: OmoMemoryReflectionLayerSchema.optional(),
22474
+ sync: OmoMemorySyncLayerSchema.optional(),
22475
+ search: OmoMemorySearchLayerSchema.optional(),
22476
+ compile_warn_tokens: number2().int().positive().optional(),
22477
+ agents: record(string2(), OmoMemoryAgentOverridesSchema).optional()
22478
+ }).strict();
22479
+ });
22480
+
22399
22481
  // packages/omo-config-core/src/schema/model-catalog.ts
22400
22482
  function isRecord5(value) {
22401
22483
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -22419,9 +22501,18 @@ var init_model_catalog = __esm(() => {
22419
22501
  });
22420
22502
 
22421
22503
  // packages/omo-config-core/src/schema/task.ts
22422
- var OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskSettingsSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
22504
+ import { availableParallelism } from "node:os";
22505
+ function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism) {
22506
+ const record2 = record(string2(), unknown()).parse(input);
22507
+ return OmoTaskSettingsSchema.parse({
22508
+ ...record2,
22509
+ residency_max_children: record2["residency_max_children"] ?? Math.max(8, resolveParallelism() * 3)
22510
+ });
22511
+ }
22512
+ var ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskSettingsSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
22423
22513
  var init_task = __esm(() => {
22424
22514
  init_zod();
22515
+ ResidencyMaxChildrenInputSchema = union([number2().int().positive(), literal("unlimited")]);
22425
22516
  OmoTaskWaitSchema = object({
22426
22517
  min_ms: number2().int().positive().default(5000),
22427
22518
  default_ms: number2().int().positive().default(60000),
@@ -22441,10 +22532,11 @@ var init_task = __esm(() => {
22441
22532
  provider_concurrency: record(string2(), number2().int().positive()).optional(),
22442
22533
  model_concurrency: record(string2(), number2().int().positive()).optional(),
22443
22534
  max_depth: number2().int().nonnegative().default(1),
22444
- residency_max_children: number2().int().positive().default(8),
22535
+ residency_max_children: ResidencyMaxChildrenInputSchema.default(8),
22445
22536
  ttl_ms: number2().int().positive().default(86400000),
22446
22537
  state_dir: string2().optional(),
22447
22538
  reattach_on_reconcile: boolean2().optional(),
22539
+ resume_children: boolean2().default(true),
22448
22540
  warnings: OmoTaskWarningsSchema.default({ unavailable_categories: true }),
22449
22541
  wait: OmoTaskWaitSchema.default({ min_ms: 5000, default_ms: 60000, max_ms: 600000 }),
22450
22542
  team: OmoTaskTeamSettingsSchema.default({
@@ -22472,10 +22564,11 @@ var init_task = __esm(() => {
22472
22564
  provider_concurrency: record(string2(), number2().int().positive()).optional(),
22473
22565
  model_concurrency: record(string2(), number2().int().positive()).optional(),
22474
22566
  max_depth: number2().int().nonnegative().optional(),
22475
- residency_max_children: number2().int().positive().optional(),
22567
+ residency_max_children: ResidencyMaxChildrenInputSchema.optional(),
22476
22568
  ttl_ms: number2().int().positive().optional(),
22477
22569
  state_dir: string2().optional(),
22478
22570
  reattach_on_reconcile: boolean2().optional(),
22571
+ resume_children: boolean2().optional(),
22479
22572
  warnings: OmoTaskWarningsLayerSchema.optional(),
22480
22573
  wait: OmoTaskWaitLayerSchema.optional(),
22481
22574
  team: OmoTaskTeamSettingsLayerSchema.optional()
@@ -22540,6 +22633,7 @@ var init_config = __esm(() => {
22540
22633
  init_agent();
22541
22634
  init_category();
22542
22635
  init_codegraph();
22636
+ init_memory();
22543
22637
  init_model_catalog();
22544
22638
  init_task();
22545
22639
  init_team();
@@ -22550,7 +22644,8 @@ var init_config = __esm(() => {
22550
22644
  codegraph: OmoCodegraphSettingsLayerSchema.optional(),
22551
22645
  task: OmoTaskSettingsLayerSchema.optional(),
22552
22646
  teams: OmoTeamsConfigLayerSchema.optional(),
22553
- models: OmoModelCatalogLayerSchema.optional()
22647
+ models: OmoModelCatalogLayerSchema.optional(),
22648
+ memory: OmoMemorySettingsLayerSchema.optional()
22554
22649
  }).strict();
22555
22650
  OmoConfigProfileSchema = object({
22556
22651
  categories: OmoCategoriesConfigSchema.optional(),
@@ -22559,6 +22654,7 @@ var init_config = __esm(() => {
22559
22654
  task: OmoTaskSettingsLayerSchema.optional(),
22560
22655
  teams: OmoTeamsConfigLayerSchema.optional(),
22561
22656
  models: OmoModelCatalogLayerSchema.optional(),
22657
+ memory: OmoMemorySettingsLayerSchema.optional(),
22562
22658
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22563
22659
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22564
22660
  "[codex]": OmoTypedHarnessConfigSchema.optional()
@@ -22571,6 +22667,7 @@ var init_config = __esm(() => {
22571
22667
  task: OmoTaskSettingsSchema.optional(),
22572
22668
  teams: OmoTeamsConfigSchema.optional(),
22573
22669
  models: OmoModelCatalogSchema.optional(),
22670
+ memory: OmoMemorySettingsSchema.optional(),
22574
22671
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22575
22672
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22576
22673
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
@@ -22586,6 +22683,7 @@ var init_config = __esm(() => {
22586
22683
  task: OmoTaskSettingsLayerSchema.optional(),
22587
22684
  teams: OmoTeamsConfigLayerSchema.optional(),
22588
22685
  models: OmoModelCatalogLayerSchema.optional(),
22686
+ memory: OmoMemorySettingsLayerSchema.optional(),
22589
22687
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
22590
22688
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
22591
22689
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
@@ -22603,6 +22701,7 @@ var init_schema = __esm(() => {
22603
22701
  init_config();
22604
22702
  init_fallback_models();
22605
22703
  init_harness();
22704
+ init_memory();
22606
22705
  init_model_catalog();
22607
22706
  init_model_ref();
22608
22707
  init_task();
@@ -22967,7 +23066,7 @@ var init_loader = __esm(() => {
22967
23066
  agents: {},
22968
23067
  categories: {},
22969
23068
  codegraph: OmoCodegraphSettingsSchema.parse({}),
22970
- task: OmoTaskSettingsSchema.parse({}),
23069
+ task: resolveOmoTaskSettings({}),
22971
23070
  teams: {}
22972
23071
  };
22973
23072
  });
@@ -23339,6 +23438,21 @@ var init_plain_object = __esm(() => {
23339
23438
  DANGEROUS_KEYS3 = new Set(["__proto__", "constructor", "prototype"]);
23340
23439
  });
23341
23440
 
23441
+ // packages/omo-config-core/src/migration/backup-move.ts
23442
+ function isCrossDeviceError(error51) {
23443
+ return error51 instanceof Error && Reflect.get(error51, "code") === "EXDEV";
23444
+ }
23445
+ function moveMigrationBackup(fileSystem, sourcePath, backupPath) {
23446
+ try {
23447
+ fileSystem.renameSync(sourcePath, backupPath);
23448
+ } catch (error51) {
23449
+ if (!isCrossDeviceError(error51))
23450
+ throw error51;
23451
+ fileSystem.copyFileSync(sourcePath, backupPath);
23452
+ fileSystem.unlinkSync(sourcePath);
23453
+ }
23454
+ }
23455
+
23342
23456
  // packages/omo-config-core/src/migration/merge.ts
23343
23457
  function displayValue(value) {
23344
23458
  const encoded = JSON.stringify(value);
@@ -23872,7 +23986,7 @@ function resumeMigrationJournal(input) {
23872
23986
  if (input.fileSystem.existsSync(move.to)) {
23873
23987
  throw new MigrationTransactionError(`Migration backup path already exists: ${move.to}`);
23874
23988
  }
23875
- input.fileSystem.renameSync(move.from, move.to);
23989
+ moveMigrationBackup(input.fileSystem, move.from, move.to);
23876
23990
  } else if (!input.fileSystem.existsSync(move.to)) {
23877
23991
  throw new MigrationTransactionError(`Migration source and backup are both missing: ${move.from}`);
23878
23992
  }
@@ -24000,7 +24114,7 @@ function executePlan(input) {
24000
24114
  input.renewLock();
24001
24115
  if (fileSystem.existsSync(move.to))
24002
24116
  throw new MigrationTransactionError(`Migration backup path already exists: ${move.to}`);
24003
- fileSystem.renameSync(move.from, move.to);
24117
+ moveMigrationBackup(fileSystem, move.from, move.to);
24004
24118
  input.onBoundary?.("source-moved");
24005
24119
  Object.assign(targetRecorded, { completedMoves: [...targetRecorded.completedMoves, move.from] });
24006
24120
  writeMigrationJournal(targetRecorded, fileSystem, env, input.process, input.clock);
@@ -24100,94 +24214,12 @@ function sgBinaryName(platform = process.platform) {
24100
24214
  }
24101
24215
  var init_sg_manifest = () => {};
24102
24216
 
24103
- // packages/utils/src/ast-grep/sg-provisioner.ts
24104
- var init_sg_provisioner = () => {};
24105
-
24106
- // packages/utils/src/ast-grep/types.ts
24107
- var SG_PATH_ENV_KEY = "OMO_AST_GREP_SG_PATH";
24108
-
24109
- // packages/utils/src/ast-grep/sg-resolver.ts
24110
- import { execFileSync as execFileSync2 } from "node:child_process";
24111
- import { existsSync as existsSync5, statSync as statSync2 } from "node:fs";
24112
- import { join as join8 } from "node:path";
24113
- function nonEmptyValue(value) {
24114
- const trimmed = value?.trim();
24115
- return trimmed === undefined || trimmed.length === 0 ? null : trimmed;
24116
- }
24117
- function defaultFileExists(filePath) {
24118
- if (!existsSync5(filePath))
24119
- return false;
24120
- try {
24121
- const stats = statSync2(filePath);
24122
- return stats.isFile() && stats.size > 0;
24123
- } catch (error51) {
24124
- if (error51 instanceof Error)
24125
- return false;
24126
- return false;
24127
- }
24128
- }
24129
- function defaultVersionProbe(binaryPath) {
24130
- return String(execFileSync2(binaryPath, ["--version"], {
24131
- encoding: "utf8",
24132
- stdio: ["ignore", "pipe", "ignore"],
24133
- timeout: 5000
24134
- }));
24135
- }
24136
- function isAstGrepVersionOutput(output) {
24137
- return output.toLowerCase().includes("ast-grep");
24138
- }
24139
- function hasAstGrepVersion(binaryPath, runVersionProbeSync) {
24140
- try {
24141
- return isAstGrepVersionOutput(runVersionProbeSync(binaryPath));
24142
- } catch (error51) {
24143
- if (error51 instanceof Error)
24144
- return false;
24145
- return false;
24146
- }
24147
- }
24148
- function pathCommandCandidates() {
24149
- return ["ast-grep", "sg"];
24150
- }
24151
- function findSgBinarySync(options = {}) {
24152
- const env = options.env ?? process.env;
24153
- const platform = options.platform ?? process.platform;
24154
- const fileExists = options.fileExists ?? defaultFileExists;
24155
- const runVersionProbeSync = options.runVersionProbeSync ?? defaultVersionProbe;
24156
- const which2 = options.which ?? bunWhich;
24157
- try {
24158
- const envOverride = nonEmptyValue(env[SG_PATH_ENV_KEY]);
24159
- if (envOverride !== null && fileExists(envOverride))
24160
- return envOverride;
24161
- if (options.runtimeDir !== undefined) {
24162
- const runtimeCandidate = join8(options.runtimeDir, sgBinaryName(platform));
24163
- if (fileExists(runtimeCandidate))
24164
- return runtimeCandidate;
24165
- }
24166
- for (const commandName of pathCommandCandidates()) {
24167
- const pathCandidate = which2(commandName);
24168
- if (pathCandidate === null || !fileExists(pathCandidate))
24169
- continue;
24170
- if (commandName !== "sg" || hasAstGrepVersion(pathCandidate, runVersionProbeSync))
24171
- return pathCandidate;
24172
- }
24173
- return null;
24174
- } catch (error51) {
24175
- if (error51 instanceof Error)
24176
- return null;
24177
- return null;
24178
- }
24179
- }
24180
- var init_sg_resolver = __esm(() => {
24181
- init_which();
24182
- init_sg_manifest();
24183
- });
24184
-
24185
24217
  // packages/utils/src/ast-grep/install-script.ts
24186
24218
  import { spawn as spawn3 } from "node:child_process";
24187
- import { existsSync as existsSync6 } from "node:fs";
24188
- import { join as join9 } from "node:path";
24219
+ import { existsSync as existsSync5 } from "node:fs";
24220
+ import { join as join8 } from "node:path";
24189
24221
  function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
24190
- return join9(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
24222
+ return join8(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
24191
24223
  }
24192
24224
  function isMissingExecutable(error51) {
24193
24225
  if (!("code" in error51))
@@ -24225,7 +24257,7 @@ function defaultSpawnProcess(command, args, options) {
24225
24257
  };
24226
24258
  }
24227
24259
  function scriptPathForPlatform(skillDir, platform) {
24228
- return join9(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
24260
+ return join8(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
24229
24261
  }
24230
24262
  function invocationsForPlatform(scriptPath, platform) {
24231
24263
  if (platform !== "win32")
@@ -24253,7 +24285,7 @@ function failedReason(outcome) {
24253
24285
  }
24254
24286
  async function runAstGrepSkillInstall(options) {
24255
24287
  const platform = options.platform ?? process.platform;
24256
- const fileExists = options.fileExists ?? existsSync6;
24288
+ const fileExists = options.fileExists ?? existsSync5;
24257
24289
  const scriptPath = scriptPathForPlatform(options.skillDir, platform);
24258
24290
  if (!fileExists(scriptPath))
24259
24291
  return { kind: "skipped", reason: `missing ${scriptPath}` };
@@ -24287,8 +24319,225 @@ var init_install_script = __esm(() => {
24287
24319
  init_sg_manifest();
24288
24320
  });
24289
24321
 
24322
+ // packages/utils/src/ast-grep/types.ts
24323
+ var SG_PATH_ENV_KEY = "OMO_AST_GREP_SG_PATH", SG_BINARY_NOT_FOUND = "BINARY_NOT_FOUND";
24324
+
24325
+ // packages/utils/src/ast-grep/sg-candidates.ts
24326
+ import { homedir } from "node:os";
24327
+ import { join as join9 } from "node:path";
24328
+ function nonEmptyValue(value) {
24329
+ const trimmed = value?.trim();
24330
+ return trimmed === undefined || trimmed.length === 0 ? null : trimmed;
24331
+ }
24332
+ function astGrepBinaryName(platform) {
24333
+ return platform === "win32" ? "ast-grep.exe" : "ast-grep";
24334
+ }
24335
+ function candidate(tier, path3) {
24336
+ return { path: path3, tier };
24337
+ }
24338
+ function envOverrideCandidates(env) {
24339
+ const override = nonEmptyValue(env[SG_PATH_ENV_KEY]);
24340
+ return override === null ? [] : [candidate("env-override", override)];
24341
+ }
24342
+ function omoRuntimeCandidates(options) {
24343
+ const binaryName = sgBinaryName(options.platform);
24344
+ const slug = runtimeSlug(options.platform, options.arch);
24345
+ const paths2 = [];
24346
+ if (options.runtimeDir !== undefined)
24347
+ paths2.push(join9(options.runtimeDir, binaryName));
24348
+ const codexHome = nonEmptyValue(options.env["CODEX_HOME"]);
24349
+ if (codexHome !== null)
24350
+ paths2.push(join9(codexHome, "runtime", "ast-grep", slug, binaryName));
24351
+ paths2.push(join9(options.homeDir, ".omo", "runtime", "ast-grep", slug, binaryName));
24352
+ return paths2.map((path3) => candidate("omo-runtime", path3));
24353
+ }
24354
+ function skillBinCandidates(options) {
24355
+ const names = [astGrepBinaryName(options.platform), sgBinaryName(options.platform)];
24356
+ const directories = [];
24357
+ const cacheDir = nonEmptyValue(options.env[AST_GREP_BIN_DIR_ENV_KEY]);
24358
+ if (cacheDir !== null)
24359
+ directories.push(cacheDir);
24360
+ if (options.packageDir !== undefined)
24361
+ directories.push(join9(options.packageDir, "bin"));
24362
+ return directories.flatMap((directory) => names.map((name) => candidate("skill-bin", join9(directory, name))));
24363
+ }
24364
+ function homebrewCandidates(platform) {
24365
+ const prefixes = platform === "darwin" || platform === "linux" || platform === "win32" ? HOMEBREW_PREFIXES[platform] : [];
24366
+ const names = [astGrepBinaryName(platform), sgBinaryName(platform)];
24367
+ return prefixes.flatMap((prefix) => names.map((name) => candidate("homebrew", join9(prefix, name))));
24368
+ }
24369
+ function planSgCandidates(options) {
24370
+ const env = options.env ?? process.env;
24371
+ const platform = options.platform ?? process.platform;
24372
+ const arch = options.arch ?? process.arch;
24373
+ const homeDir = options.homeDir ?? homedir();
24374
+ return {
24375
+ afterPath: homebrewCandidates(platform),
24376
+ beforePath: [
24377
+ ...envOverrideCandidates(env),
24378
+ ...omoRuntimeCandidates({ arch, env, homeDir, platform, runtimeDir: options.runtimeDir }),
24379
+ ...skillBinCandidates({ env, packageDir: options.packageDir, platform })
24380
+ ],
24381
+ pathCommands: ["ast-grep", "sg"]
24382
+ };
24383
+ }
24384
+ var HOMEBREW_PREFIXES;
24385
+ var init_sg_candidates = __esm(() => {
24386
+ init_install_script();
24387
+ init_sg_manifest();
24388
+ HOMEBREW_PREFIXES = {
24389
+ darwin: ["/opt/homebrew/bin", "/usr/local/bin"],
24390
+ linux: ["/home/linuxbrew/.linuxbrew/bin", "/usr/local/bin"],
24391
+ win32: []
24392
+ };
24393
+ });
24394
+
24395
+ // packages/utils/src/ast-grep/sg-install-hints.ts
24396
+ function platformHints(platform) {
24397
+ if (platform === "darwin")
24398
+ return DARWIN_HINTS;
24399
+ if (platform === "win32")
24400
+ return WIN32_HINTS;
24401
+ return LINUX_HINTS;
24402
+ }
24403
+ function sgInstallHints(platform = process.platform) {
24404
+ return [...platformHints(platform), OMO_PROVISION_HINT, ENV_OVERRIDE_HINT];
24405
+ }
24406
+ function sgBinaryNotFoundMessage(platform = process.platform) {
24407
+ 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.`;
24408
+ }
24409
+ 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;
24410
+ var init_sg_install_hints = __esm(() => {
24411
+ ENV_OVERRIDE_HINT = `Or point ${SG_PATH_ENV_KEY} at an existing ast-grep binary`;
24412
+ DARWIN_HINTS = [
24413
+ "brew install ast-grep",
24414
+ "npm install -g @ast-grep/cli",
24415
+ "cargo install ast-grep --locked"
24416
+ ];
24417
+ LINUX_HINTS = [
24418
+ "npm install -g @ast-grep/cli",
24419
+ "cargo install ast-grep --locked",
24420
+ "brew install ast-grep # linuxbrew"
24421
+ ];
24422
+ WIN32_HINTS = [
24423
+ "scoop install main/ast-grep",
24424
+ "winget install ast-grep",
24425
+ "choco install ast-grep",
24426
+ "npm install -g @ast-grep/cli"
24427
+ ];
24428
+ });
24429
+
24430
+ // packages/utils/src/ast-grep/sg-provisioner.ts
24431
+ var init_sg_provisioner = () => {};
24432
+
24433
+ // packages/utils/src/ast-grep/sg-resolver.ts
24434
+ import { execFileSync as execFileSync2 } from "node:child_process";
24435
+ import { existsSync as existsSync6, statSync as statSync2 } from "node:fs";
24436
+ function cacheFingerprint(options, plan) {
24437
+ return JSON.stringify([
24438
+ options.platform ?? process.platform,
24439
+ options.arch ?? process.arch,
24440
+ plan.beforePath.map((candidate2) => candidate2.path)
24441
+ ]);
24442
+ }
24443
+ function defaultFileExists(filePath) {
24444
+ if (!existsSync6(filePath))
24445
+ return false;
24446
+ try {
24447
+ const stats = statSync2(filePath);
24448
+ return stats.isFile() && stats.size > 0;
24449
+ } catch {
24450
+ return false;
24451
+ }
24452
+ }
24453
+ function defaultVersionProbe(binaryPath) {
24454
+ return String(execFileSync2(binaryPath, ["--version"], {
24455
+ encoding: "utf8",
24456
+ stdio: ["ignore", "pipe", "ignore"],
24457
+ timeout: SG_VERSION_PROBE_TIMEOUT_MS
24458
+ }));
24459
+ }
24460
+ function probePasses(binaryPath, deps) {
24461
+ try {
24462
+ return deps.runVersionProbeSync(binaryPath).toLowerCase().includes("ast-grep");
24463
+ } catch {
24464
+ return false;
24465
+ }
24466
+ }
24467
+ function acceptsCandidate(binaryPath, deps) {
24468
+ return deps.fileExists(binaryPath) && probePasses(binaryPath, deps);
24469
+ }
24470
+ function firstAccepted(candidates, deps) {
24471
+ for (const candidate2 of candidates) {
24472
+ if (acceptsCandidate(candidate2.path, deps))
24473
+ return { found: true, path: candidate2.path, tier: candidate2.tier };
24474
+ }
24475
+ return null;
24476
+ }
24477
+ function pathCandidates(commands, deps) {
24478
+ const resolved = [];
24479
+ for (const commandName of commands) {
24480
+ const found = deps.which(commandName);
24481
+ if (found !== null)
24482
+ resolved.push({ path: found, tier: "path" });
24483
+ }
24484
+ return resolved;
24485
+ }
24486
+ function notFound(platform) {
24487
+ return {
24488
+ error: { code: SG_BINARY_NOT_FOUND, hints: sgInstallHints(platform), message: sgBinaryNotFoundMessage(platform) },
24489
+ found: false
24490
+ };
24491
+ }
24492
+ function cacheIsStillValid(resolution2, deps, revalidate) {
24493
+ if (!resolution2.found)
24494
+ return false;
24495
+ if (!deps.fileExists(resolution2.path))
24496
+ return false;
24497
+ return !revalidate || probePasses(resolution2.path, deps);
24498
+ }
24499
+ function resolverDeps(options) {
24500
+ return {
24501
+ fileExists: options.fileExists ?? defaultFileExists,
24502
+ platform: options.platform ?? process.platform,
24503
+ runVersionProbeSync: options.runVersionProbeSync ?? defaultVersionProbe,
24504
+ which: options.which ?? bunWhich
24505
+ };
24506
+ }
24507
+ function resolveSgBinarySync(options = {}) {
24508
+ const deps = resolverDeps(options);
24509
+ const useCache = options.cache ?? true;
24510
+ try {
24511
+ const plan = planSgCandidates(options);
24512
+ const fingerprint = cacheFingerprint(options, plan);
24513
+ if (useCache && cacheEntry !== null && cacheEntry.fingerprint === fingerprint) {
24514
+ if (cacheIsStillValid(cacheEntry.resolution, deps, options.revalidate ?? false))
24515
+ return cacheEntry.resolution;
24516
+ cacheEntry = null;
24517
+ }
24518
+ const resolution2 = firstAccepted(plan.beforePath, deps) ?? firstAccepted(pathCandidates(plan.pathCommands, deps), deps) ?? firstAccepted(plan.afterPath, deps) ?? notFound(deps.platform);
24519
+ if (useCache && resolution2.found)
24520
+ cacheEntry = { fingerprint, resolution: resolution2 };
24521
+ return resolution2;
24522
+ } catch {
24523
+ return notFound(deps.platform);
24524
+ }
24525
+ }
24526
+ function findSgBinarySync(options = {}) {
24527
+ const resolution2 = resolveSgBinarySync(options);
24528
+ return resolution2.found ? resolution2.path : null;
24529
+ }
24530
+ var SG_VERSION_PROBE_TIMEOUT_MS = 5000, cacheEntry = null;
24531
+ var init_sg_resolver = __esm(() => {
24532
+ init_which();
24533
+ init_sg_candidates();
24534
+ init_sg_install_hints();
24535
+ });
24536
+
24290
24537
  // packages/utils/src/ast-grep/index.ts
24291
24538
  var init_ast_grep = __esm(() => {
24539
+ init_sg_candidates();
24540
+ init_sg_install_hints();
24292
24541
  init_sg_manifest();
24293
24542
  init_sg_provisioner();
24294
24543
  init_sg_resolver();
@@ -24296,7 +24545,7 @@ var init_ast_grep = __esm(() => {
24296
24545
  });
24297
24546
 
24298
24547
  // packages/utils/src/classify-path-environment.ts
24299
- import { homedir } from "node:os";
24548
+ import { homedir as homedir2 } from "node:os";
24300
24549
  import path3 from "node:path";
24301
24550
  function normalizeInputPath(absolutePath) {
24302
24551
  return absolutePath.replaceAll("\\", "/");
@@ -24321,7 +24570,7 @@ function classifyPathEnvironment(absolutePath) {
24321
24570
  if (normalizedPath.startsWith("/Users/") && (normalizedPath.includes("/Desktop/") || normalizedPath.endsWith("/Desktop") || normalizedPath.includes("/Documents/") || normalizedPath.endsWith("/Documents"))) {
24322
24571
  return "desktop-sync";
24323
24572
  }
24324
- const normalizedHome = normalizeInputPath(homedir());
24573
+ const normalizedHome = normalizeInputPath(homedir2());
24325
24574
  const desktopPath = normalizeInputPath(path3.join(normalizedHome, "Desktop"));
24326
24575
  const documentsPath = normalizeInputPath(path3.join(normalizedHome, "Documents"));
24327
24576
  if (isUnderPath(normalizedPath, desktopPath) || isUnderPath(normalizedPath, documentsPath)) {
@@ -24468,16 +24717,16 @@ function defaultNodeRuntime(env, fileExists, which2, nodeVersion) {
24468
24717
  }
24469
24718
  const candidates = [
24470
24719
  ...isNodeExecutableName(process.execPath) ? [process.execPath] : [],
24471
- ...CODEGRAPH_NODE_CANDIDATES.map((commandName) => which2(commandName)).filter((candidate) => candidate !== null),
24472
- ...CODEGRAPH_NODE_PATH_CANDIDATES.filter((candidate) => fileExists(candidate))
24720
+ ...CODEGRAPH_NODE_CANDIDATES.map((commandName) => which2(commandName)).filter((candidate2) => candidate2 !== null),
24721
+ ...CODEGRAPH_NODE_PATH_CANDIDATES.filter((candidate2) => fileExists(candidate2))
24473
24722
  ];
24474
24723
  const seen = new Set;
24475
- for (const candidate of candidates) {
24476
- if (seen.has(candidate))
24724
+ for (const candidate2 of candidates) {
24725
+ if (seen.has(candidate2))
24477
24726
  continue;
24478
- seen.add(candidate);
24479
- if (supportsCodegraphNodeRuntime(candidate, env, nodeVersion))
24480
- return candidate;
24727
+ seen.add(candidate2);
24728
+ if (supportsCodegraphNodeRuntime(candidate2, env, nodeVersion))
24729
+ return candidate2;
24481
24730
  }
24482
24731
  return null;
24483
24732
  }
@@ -25574,7 +25823,7 @@ function hasObjectSessionPath(input) {
25574
25823
  }
25575
25824
  function isObjectPathTypeError(error51) {
25576
25825
  const message = error51 instanceof Error ? error51.message : typeof error51 === "string" ? error51 : "";
25577
- return message.includes('The "path" property must be of type string') && message.includes("got object");
25826
+ return message.includes('The "path" property must be of type string') && (message.includes("got object") || message.includes("got undefined"));
25578
25827
  }
25579
25828
  async function dispatchWithPathCompatibility(dispatch, input) {
25580
25829
  try {
@@ -26221,7 +26470,26 @@ var init_model_requirements = __esm(() => {
26221
26470
  });
26222
26471
 
26223
26472
  // packages/model-core/src/model-family-detectors.ts
26224
- var init_model_family_detectors = () => {};
26473
+ function extractModelName(model) {
26474
+ return model.includes("/") ? model.split("/").pop() ?? model : model;
26475
+ }
26476
+ function isClaudeOpus47OrLaterModel(model) {
26477
+ const modelName = extractModelName(model).toLowerCase().replaceAll(".", "-");
26478
+ if (modelName.includes("claude-fable"))
26479
+ return true;
26480
+ const match = CLAUDE_OPUS_VERSION_RE.exec(modelName);
26481
+ if (!match)
26482
+ return false;
26483
+ const major = Number(match[1]);
26484
+ const minor = match[2] === undefined ? 0 : Number(match[2]);
26485
+ if (Number.isNaN(major) || Number.isNaN(minor))
26486
+ return false;
26487
+ return major > 4 || major === 4 && minor >= 7;
26488
+ }
26489
+ var CLAUDE_OPUS_VERSION_RE;
26490
+ var init_model_family_detectors = __esm(() => {
26491
+ CLAUDE_OPUS_VERSION_RE = /claude-opus-(\d+)(?:-(\d+))?/;
26492
+ });
26225
26493
 
26226
26494
  // packages/model-core/src/model-capability-aliases.ts
26227
26495
  function normalizeLookupModelID(modelID) {
@@ -26319,9 +26587,83 @@ function normalizeModelID(modelID) {
26319
26587
  return modelID.replace(/\.(\d+)/g, "-$1");
26320
26588
  }
26321
26589
 
26590
+ // packages/model-core/src/reasoning-level.ts
26591
+ function isReasoningLevelOrAuto(value) {
26592
+ return REASONING_LEVEL_OR_AUTO_SET2.has(value);
26593
+ }
26594
+ function clampReasoningLevel(value, allowed) {
26595
+ const ladder = REASONING_LEVELS2;
26596
+ const requestedIndex = ladder.indexOf(value);
26597
+ if (requestedIndex === -1)
26598
+ return;
26599
+ for (let index = requestedIndex;index >= 0; index -= 1) {
26600
+ const candidate2 = REASONING_LEVELS2[index];
26601
+ if (candidate2 !== undefined && allowed.includes(candidate2))
26602
+ return candidate2;
26603
+ }
26604
+ return;
26605
+ }
26606
+ function splitReasoningSuffix2(model, options) {
26607
+ if (typeof model !== "string")
26608
+ return { base: "" };
26609
+ const trimmed = model.trim();
26610
+ if (!trimmed)
26611
+ return { base: "" };
26612
+ const separatorIndex = trimmed.lastIndexOf(":");
26613
+ if (separatorIndex === -1)
26614
+ return { base: trimmed };
26615
+ const base = trimmed.slice(0, separatorIndex).trim();
26616
+ const token = trimmed.slice(separatorIndex + 1).trim().toLowerCase();
26617
+ if (!base || !isReasoningLevelOrAuto(token))
26618
+ return { base: trimmed };
26619
+ if (token === "max" && !(options?.allowMaxSuffix ?? base.includes("/")))
26620
+ return { base: trimmed };
26621
+ return { base, level: token };
26622
+ }
26623
+ var REASONING_LEVELS2, REASONING_AUTO2 = "auto", REASONING_LEVEL_SET2, REASONING_LEVEL_OR_AUTO_SET2;
26624
+ var init_reasoning_level = __esm(() => {
26625
+ REASONING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
26626
+ REASONING_LEVEL_SET2 = new Set(REASONING_LEVELS2);
26627
+ REASONING_LEVEL_OR_AUTO_SET2 = new Set([...REASONING_LEVELS2, REASONING_AUTO2]);
26628
+ });
26629
+
26630
+ // packages/model-core/src/model-string-parser.ts
26631
+ function parseVariantFromModelID(rawModelID, options) {
26632
+ if (typeof rawModelID !== "string") {
26633
+ return { modelID: "" };
26634
+ }
26635
+ const trimmedModelID = rawModelID.trim();
26636
+ if (!trimmedModelID) {
26637
+ return { modelID: "" };
26638
+ }
26639
+ const parenthesizedVariant = trimmedModelID.match(/^(.*)\(([^()]+)\)\s*$/);
26640
+ if (parenthesizedVariant) {
26641
+ const modelID = parenthesizedVariant[1]?.trim() ?? "";
26642
+ const variant = parenthesizedVariant[2]?.trim();
26643
+ return variant ? { modelID, variant } : { modelID };
26644
+ }
26645
+ const suffixedModel = splitReasoningSuffix2(trimmedModelID, options);
26646
+ if (suffixedModel.level) {
26647
+ return { modelID: suffixedModel.base, variant: suffixedModel.level };
26648
+ }
26649
+ const spaceVariant = trimmedModelID.match(/^(.*\S)\s+([a-z][a-z0-9_-]*)$/i);
26650
+ if (spaceVariant) {
26651
+ const modelID = spaceVariant[1]?.trim() ?? "";
26652
+ const variant = spaceVariant[2]?.trim().toLowerCase();
26653
+ if (variant) {
26654
+ return { modelID, variant };
26655
+ }
26656
+ }
26657
+ return { modelID: trimmedModelID };
26658
+ }
26659
+ var init_model_string_parser = __esm(() => {
26660
+ init_reasoning_level();
26661
+ });
26662
+
26322
26663
  // packages/model-core/src/model-capability-heuristics.ts
26323
26664
  function detectHeuristicModelFamily(modelID) {
26324
- const normalizedModelID = normalizeModelID(modelID).toLowerCase();
26665
+ const parsedModel = parseVariantFromModelID(modelID, { allowMaxSuffix: true });
26666
+ const normalizedModelID = normalizeModelID(parsedModel.modelID).toLowerCase();
26325
26667
  for (const definition of HEURISTIC_MODEL_FAMILY_REGISTRY) {
26326
26668
  if (definition.pattern?.test(normalizedModelID)) {
26327
26669
  return definition;
@@ -26334,6 +26676,7 @@ function detectHeuristicModelFamily(modelID) {
26334
26676
  }
26335
26677
  var HEURISTIC_MODEL_FAMILY_REGISTRY;
26336
26678
  var init_model_capability_heuristics = __esm(() => {
26679
+ init_model_string_parser();
26337
26680
  HEURISTIC_MODEL_FAMILY_REGISTRY = [
26338
26681
  {
26339
26682
  family: "claude-opus",
@@ -26347,11 +26690,19 @@ var init_model_capability_heuristics = __esm(() => {
26347
26690
  variants: ["low", "medium", "high"],
26348
26691
  supportsThinking: true
26349
26692
  },
26693
+ {
26694
+ family: "openai-deep-research",
26695
+ includes: ["o3-deep-research", "o4-mini-deep-research"],
26696
+ variants: ["low", "medium", "high"],
26697
+ reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
26698
+ supportsTemperature: true
26699
+ },
26350
26700
  {
26351
26701
  family: "openai-reasoning",
26352
26702
  pattern: /(?:^|\/)o\d(?:$|-)/,
26353
26703
  variants: ["low", "medium", "high"],
26354
- reasoningEfforts: ["none", "minimal", "low", "medium", "high"]
26704
+ reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
26705
+ supportsTemperature: false
26355
26706
  },
26356
26707
  {
26357
26708
  family: "gpt-5",
@@ -26395,7 +26746,13 @@ var init_model_capability_heuristics = __esm(() => {
26395
26746
  {
26396
26747
  family: "glm",
26397
26748
  includes: ["glm"],
26398
- variants: ["low", "medium", "high"]
26749
+ variants: ["low", "medium", "high", "max"],
26750
+ reasoningEfforts: ["high", "max"],
26751
+ reasoningEffortAliases: {
26752
+ low: "high",
26753
+ medium: "high",
26754
+ xhigh: "max"
26755
+ }
26399
26756
  },
26400
26757
  {
26401
26758
  family: "minimax",
@@ -26430,26 +26787,6 @@ var init_model_capability_heuristics = __esm(() => {
26430
26787
  // packages/model-core/src/model-capability-guardrails.ts
26431
26788
  var init_model_capability_guardrails = () => {};
26432
26789
 
26433
- // packages/model-core/src/reasoning-level.ts
26434
- function clampReasoningLevel(value, allowed) {
26435
- const ladder = REASONING_LEVELS2;
26436
- const requestedIndex = ladder.indexOf(value);
26437
- if (requestedIndex === -1)
26438
- return;
26439
- for (let index = requestedIndex;index >= 0; index -= 1) {
26440
- const candidate = REASONING_LEVELS2[index];
26441
- if (candidate !== undefined && allowed.includes(candidate))
26442
- return candidate;
26443
- }
26444
- return;
26445
- }
26446
- var REASONING_LEVELS2, REASONING_AUTO2 = "auto", REASONING_LEVEL_SET2, REASONING_LEVEL_OR_AUTO_SET2;
26447
- var init_reasoning_level = __esm(() => {
26448
- REASONING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
26449
- REASONING_LEVEL_SET2 = new Set(REASONING_LEVELS2);
26450
- REASONING_LEVEL_OR_AUTO_SET2 = new Set([...REASONING_LEVELS2, REASONING_AUTO2]);
26451
- });
26452
-
26453
26790
  // packages/model-core/src/model-settings-compatibility.ts
26454
26791
  function downgradeWithinLadder(value, allowed) {
26455
26792
  return clampReasoningLevel(value, allowed);
@@ -26517,12 +26854,14 @@ function resolveCompatibleModelSettings(input) {
26517
26854
  reasoningEffort = resolved.value;
26518
26855
  }
26519
26856
  let temperature = input.desired.temperature;
26520
- if (temperature !== undefined && input.capabilities?.supportsTemperature === false) {
26857
+ const metadataSupportsTemperature = input.capabilities?.supportsTemperature;
26858
+ const familyDisallowsTemperature = metadataSupportsTemperature === undefined && (isClaudeOpus47OrLaterModel(input.modelID) || family?.supportsTemperature === false);
26859
+ if (temperature !== undefined && (metadataSupportsTemperature === false || familyDisallowsTemperature)) {
26521
26860
  changes.push({
26522
26861
  field: "temperature",
26523
26862
  from: String(temperature),
26524
26863
  to: undefined,
26525
- reason: "unsupported-by-model-metadata"
26864
+ reason: metadataSupportsTemperature === false ? "unsupported-by-model-metadata" : "unsupported-by-model-family"
26526
26865
  });
26527
26866
  temperature = undefined;
26528
26867
  }
@@ -26571,6 +26910,7 @@ function resolveCompatibleModelSettings(input) {
26571
26910
  }
26572
26911
  var init_model_settings_compatibility = __esm(() => {
26573
26912
  init_model_capability_heuristics();
26913
+ init_model_family_detectors();
26574
26914
  init_reasoning_level();
26575
26915
  });
26576
26916
 
@@ -26651,9 +26991,6 @@ function normalizeFallbackModels(models2) {
26651
26991
  }
26652
26992
  var init_model_resolver = () => {};
26653
26993
 
26654
- // packages/model-core/src/model-string-parser.ts
26655
- var init_model_string_parser = () => {};
26656
-
26657
26994
  // packages/model-core/src/fallback-chain-from-models.ts
26658
26995
  var init_fallback_chain_from_models = () => {};
26659
26996
 
@@ -26969,14 +27306,89 @@ function getProviderOverride(providerID, modelID) {
26969
27306
  return;
26970
27307
  return GITHUB_COPILOT_GPT5_MODEL.test(normalizeLookupModelID2(modelID)) ? GITHUB_COPILOT_GPT5_OVERRIDE : undefined;
26971
27308
  }
27309
+ function stripSameProviderPrefix(providerID, modelID) {
27310
+ const prefix = `${providerID.trim()}/`;
27311
+ return prefix !== "/" && modelID.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase() ? modelID.slice(prefix.length) : undefined;
27312
+ }
27313
+ function buildLookupCandidates(providerID, modelID) {
27314
+ const bareModelID = parseVariantFromModelID(modelID, { allowMaxSuffix: true }).modelID;
27315
+ const candidates = [
27316
+ modelID,
27317
+ stripSameProviderPrefix(providerID, modelID),
27318
+ bareModelID,
27319
+ stripSameProviderPrefix(providerID, bareModelID)
27320
+ ];
27321
+ const uniqueCandidates = [];
27322
+ const seen = new Set;
27323
+ for (const candidate2 of candidates) {
27324
+ if (!candidate2 || seen.has(candidate2))
27325
+ continue;
27326
+ seen.add(candidate2);
27327
+ uniqueCandidates.push(candidate2);
27328
+ }
27329
+ return uniqueCandidates;
27330
+ }
27331
+ function findProviderMetadata(providerCache, providerID, modelID) {
27332
+ if (!providerCache)
27333
+ return;
27334
+ for (const candidate2 of buildLookupCandidates(providerID, modelID)) {
27335
+ const match = providerCache.findProviderModelMetadata(providerID, candidate2);
27336
+ if (match)
27337
+ return match;
27338
+ }
27339
+ return;
27340
+ }
27341
+ function findSnapshotEntry(snapshot, providerID, modelIDs) {
27342
+ if (!snapshot)
27343
+ return;
27344
+ const normalizedProviderID = providerID.trim();
27345
+ const providerSpecificCandidates = [];
27346
+ const generalCandidates = [];
27347
+ for (const modelID of modelIDs) {
27348
+ const strippedModelID = stripSameProviderPrefix(providerID, modelID);
27349
+ const unqualifiedModelID = strippedModelID ?? (modelID.includes("/") ? undefined : modelID);
27350
+ if (!unqualifiedModelID) {
27351
+ generalCandidates.push(...buildLookupCandidates(providerID, modelID));
27352
+ continue;
27353
+ }
27354
+ const bareModelID = parseVariantFromModelID(unqualifiedModelID, { allowMaxSuffix: true }).modelID;
27355
+ if (normalizedProviderID) {
27356
+ providerSpecificCandidates.push(`${normalizedProviderID}/${unqualifiedModelID}`, `${normalizedProviderID}/${bareModelID}`);
27357
+ }
27358
+ generalCandidates.push(unqualifiedModelID, bareModelID);
27359
+ }
27360
+ const seen = new Set;
27361
+ for (const candidate2 of [...providerSpecificCandidates, ...generalCandidates]) {
27362
+ if (seen.has(candidate2))
27363
+ continue;
27364
+ seen.add(candidate2);
27365
+ const entry = snapshot.models[candidate2];
27366
+ if (entry)
27367
+ return entry;
27368
+ }
27369
+ return;
27370
+ }
27371
+ function resolveCapabilityModelAlias(modelID, providerID) {
27372
+ const direct = resolveModelIDAlias(modelID, providerID);
27373
+ if (direct.source !== "canonical")
27374
+ return direct;
27375
+ const bareModelID = parseVariantFromModelID(modelID, { allowMaxSuffix: true }).modelID;
27376
+ if (bareModelID === modelID)
27377
+ return direct;
27378
+ const bareAlias = resolveModelIDAlias(bareModelID, providerID);
27379
+ return bareAlias.source === "canonical" ? direct : { ...bareAlias, requestedModelID: modelID };
27380
+ }
26972
27381
  function getModelCapabilities(input) {
26973
- const canonicalization = resolveModelIDAlias(input.modelID, input.providerID);
27382
+ const canonicalization = resolveCapabilityModelAlias(input.modelID, input.providerID);
26974
27383
  const override = getOverride(input.modelID);
26975
27384
  const providerOverride = getProviderOverride(input.providerID, canonicalization.canonicalModelID);
26976
- const runtimeModel = readRuntimeModel(input.runtimeModel ?? input.providerCache?.findProviderModelMetadata(input.providerID, input.modelID));
27385
+ const runtimeModel = readRuntimeModel(input.runtimeModel ?? findProviderMetadata(input.providerCache, input.providerID, input.modelID));
26977
27386
  const runtimeSnapshot = input.runtimeSnapshot;
26978
27387
  const bundledSnapshot = input.bundledSnapshot;
26979
- const snapshotEntry = runtimeSnapshot?.models?.[canonicalization.canonicalModelID] ?? bundledSnapshot?.models?.[canonicalization.canonicalModelID];
27388
+ const snapshotModelIDs = canonicalization.source === "canonical" ? [input.modelID, canonicalization.canonicalModelID] : [canonicalization.canonicalModelID, input.modelID];
27389
+ const runtimeSnapshotEntry = findSnapshotEntry(runtimeSnapshot, input.providerID, snapshotModelIDs);
27390
+ const bundledSnapshotEntry = findSnapshotEntry(bundledSnapshot, input.providerID, snapshotModelIDs);
27391
+ const snapshotEntry = runtimeSnapshotEntry ?? bundledSnapshotEntry;
26980
27392
  const heuristicFamily = detectHeuristicModelFamily(canonicalization.canonicalModelID);
26981
27393
  const runtimeVariants = readRuntimeModelVariants(runtimeModel);
26982
27394
  const runtimeReasoning = readRuntimeModelReasoningSupport(runtimeModel);
@@ -26986,7 +27398,7 @@ function getModelCapabilities(input) {
26986
27398
  const runtimeMaxOutputTokens = readRuntimeModelLimitOutput(runtimeModel);
26987
27399
  const runtimeToolCall = readRuntimeModelToolCallSupport(runtimeModel);
26988
27400
  const runtimeModalities = readRuntimeModelModalities(runtimeModel);
26989
- const snapshotSource = runtimeSnapshot?.models?.[canonicalization.canonicalModelID] ? "runtime-snapshot" : bundledSnapshot?.models?.[canonicalization.canonicalModelID] ? "bundled-snapshot" : "none";
27401
+ const snapshotSource = runtimeSnapshotEntry ? "runtime-snapshot" : bundledSnapshotEntry ? "bundled-snapshot" : "none";
26990
27402
  const familySource = snapshotEntry?.family ? "snapshot" : heuristicFamily?.family ? "heuristic" : "none";
26991
27403
  const variantsSource = runtimeVariants ? "runtime" : providerOverride?.variants ? "override" : override?.variants ? "override" : heuristicFamily?.variants ? "heuristic" : "none";
26992
27404
  const reasoningEffortsSource = providerOverride?.reasoningEfforts ? "override" : override?.reasoningEfforts ? "override" : heuristicFamily?.reasoningEfforts ? "heuristic" : "none";
@@ -27035,6 +27447,7 @@ var MODEL_ID_OVERRIDES, GITHUB_COPILOT_GPT5_MODEL, GITHUB_COPILOT_GPT5_OVERRIDE;
27035
27447
  var init_get_model_capabilities = __esm(() => {
27036
27448
  init_model_capability_aliases();
27037
27449
  init_model_capability_heuristics();
27450
+ init_model_string_parser();
27038
27451
  MODEL_ID_OVERRIDES = {};
27039
27452
  GITHUB_COPILOT_GPT5_MODEL = /(?:^|\/)gpt-5(?:[.-]|$)/;
27040
27453
  GITHUB_COPILOT_GPT5_OVERRIDE = {
@@ -27570,15 +27983,15 @@ var init_kimi_categories = __esm(() => {
27570
27983
  });
27571
27984
 
27572
27985
  // packages/omo-opencode/src/agents/types.ts
27573
- function extractModelName(model) {
27986
+ function extractModelName2(model) {
27574
27987
  return model.includes("/") ? model.split("/").pop() ?? model : model;
27575
27988
  }
27576
27989
  function isGpt5_5Model(model) {
27577
- const modelName = extractModelName(model).toLowerCase();
27990
+ const modelName = extractModelName2(model).toLowerCase();
27578
27991
  return modelName.includes("gpt-5.5") || modelName.includes("gpt-5-5");
27579
27992
  }
27580
27993
  function isGpt5_6Model(model) {
27581
- const modelName = extractModelName(model).toLowerCase();
27994
+ const modelName = extractModelName2(model).toLowerCase();
27582
27995
  return modelName.includes("gpt-5.6") || modelName.includes("gpt-5-6");
27583
27996
  }
27584
27997
  var init_types4 = () => {};
@@ -27790,7 +28203,7 @@ var init_migration3 = __esm(() => {
27790
28203
 
27791
28204
  // packages/omo-opencode/src/shared/opencode-config-dir.ts
27792
28205
  import { existsSync as existsSync8, realpathSync as realpathSync3 } from "node:fs";
27793
- import { homedir as homedir3 } from "node:os";
28206
+ import { homedir as homedir4 } from "node:os";
27794
28207
  import { join as join12, posix as posix4, resolve as resolve4, win32 } from "node:path";
27795
28208
  function isDevBuild(version2) {
27796
28209
  if (!version2)
@@ -27801,14 +28214,14 @@ function getTauriConfigDir(identifier) {
27801
28214
  const platform = process.platform;
27802
28215
  switch (platform) {
27803
28216
  case "darwin":
27804
- return join12(homedir3(), "Library", "Application Support", identifier);
28217
+ return join12(homedir4(), "Library", "Application Support", identifier);
27805
28218
  case "win32": {
27806
- const appData = process.env.APPDATA || join12(homedir3(), "AppData", "Roaming");
28219
+ const appData = process.env.APPDATA || join12(homedir4(), "AppData", "Roaming");
27807
28220
  return win32.join(appData, identifier);
27808
28221
  }
27809
28222
  case "linux":
27810
28223
  default: {
27811
- const xdgConfig = process.env.XDG_CONFIG_HOME || join12(homedir3(), ".config");
28224
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join12(homedir4(), ".config");
27812
28225
  return join12(xdgConfig, identifier);
27813
28226
  }
27814
28227
  }
@@ -27852,7 +28265,7 @@ function getWslLinuxHomeDir(windowsConfigRoot) {
27852
28265
  function getCliDefaultConfigDir() {
27853
28266
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
27854
28267
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment() && isWindowsUserConfigRoot(envXdgConfig);
27855
- const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join12(homedir3(), ".config");
28268
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join12(homedir4(), ".config");
27856
28269
  const configDir = isWslEnvironment() ? posix4.join(xdgConfig, "opencode") : join12(xdgConfig, "opencode");
27857
28270
  return resolveConfigPath(configDir);
27858
28271
  }
@@ -86726,7 +87139,7 @@ function toFallbackModelObject(entry, provider) {
86726
87139
  }
86727
87140
  function collectAvailableFallbacks(fallbackChain, availability) {
86728
87141
  const expandedFallbacks = fallbackChain.flatMap((entry) => entry.providers.filter((provider) => isProviderAvailable(provider, availability)).map((provider) => toFallbackModelObject(entry, provider)));
86729
- return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate) => candidate.model === entry.model && candidate.variant === entry.variant) === index);
87142
+ return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate2) => candidate2.model === entry.model && candidate2.variant === entry.variant) === index);
86730
87143
  }
86731
87144
  function attachFallbackModels(config3, fallbackChain, availability) {
86732
87145
  const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
@@ -87016,12 +87429,12 @@ function configRoots(options) {
87016
87429
  ];
87017
87430
  const seen = new Set;
87018
87431
  const result = [];
87019
- for (const candidate of candidates) {
87020
- const key = pathKey(candidate.path, options);
87432
+ for (const candidate2 of candidates) {
87433
+ const key = pathKey(candidate2.path, options);
87021
87434
  if (seen.has(key))
87022
87435
  continue;
87023
87436
  seen.add(key);
87024
- result.push({ ...candidate, path: canonicalPath(candidate.path, options) });
87437
+ result.push({ ...candidate2, path: canonicalPath(candidate2.path, options) });
87025
87438
  }
87026
87439
  return result;
87027
87440
  }
@@ -87165,10 +87578,10 @@ function historyValues(value) {
87165
87578
  return [];
87166
87579
  const values = [];
87167
87580
  for (const key of ["_migrations", "appliedMigrations"]) {
87168
- const candidate = value[key];
87169
- if (!Array.isArray(candidate))
87581
+ const candidate2 = value[key];
87582
+ if (!Array.isArray(candidate2))
87170
87583
  continue;
87171
- for (const item of candidate) {
87584
+ for (const item of candidate2) {
87172
87585
  if (typeof item === "string" && !values.includes(item))
87173
87586
  values.push(item);
87174
87587
  }
@@ -88275,20 +88688,20 @@ var init_config_manager = __esm(() => {
88275
88688
 
88276
88689
  // packages/telemetry-core/src/activity-state.ts
88277
88690
  import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as readFileSync12 } from "node:fs";
88278
- import { basename as basename9, join as join52 } from "node:path";
88691
+ import { basename as basename9, join as join53 } from "node:path";
88279
88692
  function resolveTelemetryStateDir(product, options = {}) {
88280
88693
  const dataDir = resolveXdgDataDir(product.cacheDirName, {
88281
88694
  env: options.env,
88282
88695
  osProvider: options.osProvider
88283
88696
  });
88284
- const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join52(options.env.XDG_DATA_HOME, product.cacheDirName);
88697
+ const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join53(options.env.XDG_DATA_HOME, product.cacheDirName);
88285
88698
  if (dataDir === xdgStateDir || xdgStateDir === undefined && basename9(dataDir) === product.cacheDirName) {
88286
88699
  return dataDir;
88287
88700
  }
88288
- return join52(dataDir, product.cacheDirName);
88701
+ return join53(dataDir, product.cacheDirName);
88289
88702
  }
88290
88703
  function getTelemetryActivityStateFilePath(stateDir) {
88291
- return join52(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
88704
+ return join53(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
88292
88705
  }
88293
88706
  function getDailyActiveCaptureState(input) {
88294
88707
  const state = readPostHogActivityState(input.stateDir, input.diagnostics);
@@ -88359,9 +88772,9 @@ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY =
88359
88772
 
88360
88773
  // packages/telemetry-core/src/diagnostics.ts
88361
88774
  import { appendFileSync as appendFileSync2, existsSync as existsSync27, mkdirSync as mkdirSync9, readFileSync as readFileSync13 } from "node:fs";
88362
- import { join as join53 } from "node:path";
88775
+ import { join as join54 } from "node:path";
88363
88776
  function getTelemetryDiagnosticsFilePath(diagnosticsDir) {
88364
- return join53(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
88777
+ return join54(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
88365
88778
  }
88366
88779
  function writeTelemetryDiagnostic(input, options) {
88367
88780
  const now = options.now ?? new Date;
@@ -88835,21 +89248,21 @@ var init_string_utils = () => {};
88835
89248
  function isPrimitive(value) {
88836
89249
  return value === null || typeof value != "object";
88837
89250
  }
88838
- function isBuiltin(candidate, className) {
88839
- return Object.prototype.toString.call(candidate) === `[object ${className}]`;
89251
+ function isBuiltin(candidate2, className) {
89252
+ return Object.prototype.toString.call(candidate2) === `[object ${className}]`;
88840
89253
  }
88841
89254
  function isErrorEvent(event) {
88842
89255
  return isBuiltin(event, "ErrorEvent");
88843
89256
  }
88844
- function isEvent(candidate) {
88845
- return typeof Event != "undefined" && isInstanceOf(candidate, Event);
89257
+ function isEvent(candidate2) {
89258
+ return typeof Event != "undefined" && isInstanceOf(candidate2, Event);
88846
89259
  }
88847
- function isPlainObject5(candidate) {
88848
- return isBuiltin(candidate, "Object");
89260
+ function isPlainObject5(candidate2) {
89261
+ return isBuiltin(candidate2, "Object");
88849
89262
  }
88850
- function isInstanceOf(candidate, base) {
89263
+ function isInstanceOf(candidate2, base) {
88851
89264
  try {
88852
- return candidate instanceof base;
89265
+ return candidate2 instanceof base;
88853
89266
  } catch {
88854
89267
  return false;
88855
89268
  }
@@ -89994,8 +90407,8 @@ class DOMExceptionCoercer {
89994
90407
  synthetic: false
89995
90408
  };
89996
90409
  }
89997
- getType(candidate) {
89998
- return this.isDOMError(candidate) ? "DOMError" : "DOMException";
90410
+ getType(candidate2) {
90411
+ return this.isDOMError(candidate2) ? "DOMError" : "DOMException";
89999
90412
  }
90000
90413
  getValue(err) {
90001
90414
  const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
@@ -90080,10 +90493,10 @@ class StringCoercer {
90080
90493
  synthetic: true
90081
90494
  };
90082
90495
  }
90083
- getInfos(candidate) {
90496
+ getInfos(candidate2) {
90084
90497
  let type = "Error";
90085
- let value = candidate;
90086
- const groups = candidate.match(ERROR_TYPES_PATTERN);
90498
+ let value = candidate2;
90499
+ const groups = candidate2.match(ERROR_TYPES_PATTERN);
90087
90500
  if (groups) {
90088
90501
  type = groups[1];
90089
90502
  value = groups[2];
@@ -90132,18 +90545,18 @@ var init_utils2 = () => {};
90132
90545
 
90133
90546
  // node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
90134
90547
  class ObjectCoercer {
90135
- match(candidate) {
90136
- return typeof candidate == "object" && candidate !== null;
90548
+ match(candidate2) {
90549
+ return typeof candidate2 == "object" && candidate2 !== null;
90137
90550
  }
90138
- coerce(candidate, ctx) {
90139
- const errorProperty = this.getErrorPropertyFromObject(candidate);
90551
+ coerce(candidate2, ctx) {
90552
+ const errorProperty = this.getErrorPropertyFromObject(candidate2);
90140
90553
  if (errorProperty)
90141
90554
  return ctx.apply(errorProperty);
90142
90555
  return {
90143
- type: this.getType(candidate),
90144
- value: this.getValue(candidate),
90556
+ type: this.getType(candidate2),
90557
+ value: this.getValue(candidate2),
90145
90558
  stack: ctx.syntheticException?.stack,
90146
- level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
90559
+ level: this.isSeverityLevel(candidate2.level) ? candidate2.level : "error",
90147
90560
  synthetic: true
90148
90561
  };
90149
90562
  }
@@ -90211,8 +90624,8 @@ var init_event_coercer = __esm(() => {
90211
90624
 
90212
90625
  // node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
90213
90626
  class PrimitiveCoercer {
90214
- match(candidate) {
90215
- return isPrimitive(candidate);
90627
+ match(candidate2) {
90628
+ return isPrimitive(candidate2);
90216
90629
  }
90217
90630
  coerce(value, ctx) {
90218
90631
  return {
@@ -94082,7 +94495,7 @@ var package_default2;
94082
94495
  var init_package2 = __esm(() => {
94083
94496
  package_default2 = {
94084
94497
  name: "@oh-my-opencode/omo-codex",
94085
- version: "4.19.4",
94498
+ version: "5.0.0-beta.2",
94086
94499
  type: "module",
94087
94500
  private: true,
94088
94501
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -94474,8 +94887,8 @@ import * as fs3 from "node:fs";
94474
94887
  import * as path8 from "node:path";
94475
94888
  function findPackageJsonUp(startPath) {
94476
94889
  try {
94477
- const stat6 = fs3.statSync(startPath);
94478
- let dir = stat6.isDirectory() ? startPath : path8.dirname(startPath);
94890
+ const stat7 = fs3.statSync(startPath);
94891
+ let dir = stat7.isDirectory() ? startPath : path8.dirname(startPath);
94479
94892
  for (let i = 0;i < 10; i++) {
94480
94893
  const pkgPath = path8.join(dir, "package.json");
94481
94894
  if (fs3.existsSync(pkgPath)) {
@@ -94596,10 +95009,10 @@ function getCachedVersion(options = {}) {
94596
95009
  log2("[auto-update-checker] Failed to resolve version from current directory:", err);
94597
95010
  }
94598
95011
  }
94599
- for (const candidate of packageJsonCandidates) {
95012
+ for (const candidate2 of packageJsonCandidates) {
94600
95013
  try {
94601
- if (fs6.existsSync(candidate)) {
94602
- return readPackageVersion(candidate);
95014
+ if (fs6.existsSync(candidate2)) {
95015
+ return readPackageVersion(candidate2);
94603
95016
  }
94604
95017
  } catch (err) {
94605
95018
  if (err instanceof Error) {
@@ -95051,20 +95464,20 @@ var init_update_toasts = __esm(() => {
95051
95464
  });
95052
95465
 
95053
95466
  // packages/omo-opencode/src/hooks/auto-update-checker/hook/background-update-check.ts
95054
- import { existsSync as existsSync45 } from "node:fs";
95055
- import { dirname as dirname26, join as join70 } from "node:path";
95467
+ import { existsSync as existsSync46 } from "node:fs";
95468
+ import { dirname as dirname28, join as join73 } from "node:path";
95056
95469
  import { fileURLToPath as fileURLToPath5 } from "node:url";
95057
95470
  function defaultGetModuleHostingWorkspace() {
95058
95471
  try {
95059
- const currentDir = dirname26(fileURLToPath5(import.meta.url));
95472
+ const currentDir = dirname28(fileURLToPath5(import.meta.url));
95060
95473
  const pkgJsonPath = findPackageJsonUp(currentDir);
95061
95474
  if (!pkgJsonPath)
95062
95475
  return null;
95063
- const pkgDir = dirname26(pkgJsonPath);
95064
- const nodeModulesDir = dirname26(pkgDir);
95476
+ const pkgDir = dirname28(pkgJsonPath);
95477
+ const nodeModulesDir = dirname28(pkgDir);
95065
95478
  if (nodeModulesDir.split(/[\\/]/).pop() !== "node_modules")
95066
95479
  return null;
95067
- return dirname26(nodeModulesDir);
95480
+ return dirname28(nodeModulesDir);
95068
95481
  } catch (error51) {
95069
95482
  if (error51 instanceof Error) {
95070
95483
  return null;
@@ -95205,8 +95618,8 @@ var init_background_update_check = __esm(() => {
95205
95618
  init_package_json_locator();
95206
95619
  init_update_toasts();
95207
95620
  defaultDeps4 = {
95208
- existsSync: existsSync45,
95209
- join: join70,
95621
+ existsSync: existsSync46,
95622
+ join: join73,
95210
95623
  runBunInstallWithDetails,
95211
95624
  log: log2,
95212
95625
  getOpenCodeCacheDir,
@@ -95369,7 +95782,7 @@ async function showSpinnerToast(ctx, version3, message) {
95369
95782
  duration: frameInterval + 50
95370
95783
  }
95371
95784
  }).catch(ignoreToastError);
95372
- await new Promise((resolve18) => setTimeout(resolve18, frameInterval));
95785
+ await new Promise((resolve20) => setTimeout(resolve20, frameInterval));
95373
95786
  }
95374
95787
  }
95375
95788
  var SISYPHUS_SPINNER;
@@ -95815,9 +96228,9 @@ function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
95815
96228
  }
95816
96229
 
95817
96230
  // packages/omo-codex/src/install/install-codex.ts
95818
- import { join as join54, resolve as resolve13 } from "node:path";
96231
+ import { join as join55, resolve as resolve13 } from "node:path";
95819
96232
  import { existsSync as existsSync28 } from "node:fs";
95820
- import { homedir as homedir5 } from "node:os";
96233
+ import { homedir as homedir6 } from "node:os";
95821
96234
 
95822
96235
  // packages/omo-codex/src/install/codex-cache-bins.ts
95823
96236
  import { chmod, lstat as lstat4, mkdir, readFile as readFile3, readdir as readdir2, readlink as readlink3, rm as rm3, stat as stat2, symlink, writeFile } from "node:fs/promises";
@@ -95986,6 +96399,11 @@ var LEGACY_CODEX_COMPONENT_BINS = [
95986
96399
  { name: "codex-telemetry", component: "telemetry" },
95987
96400
  { name: "codex-ultrawork", component: "ultrawork" }
95988
96401
  ];
96402
+ var LEGACY_CODEX_COMPONENT_BIN_NAMES = LEGACY_CODEX_COMPONENT_BINS.map((entry) => entry.name);
96403
+ function isLegacyCodexBinTarget(binName, target) {
96404
+ const entry = LEGACY_CODEX_COMPONENT_BINS.find((candidate2) => candidate2.name === binName);
96405
+ return entry !== undefined && isManagedLegacyComponentTarget(target, entry.component);
96406
+ }
95989
96407
  async function removeLegacyCodexComponentBins(binDir, platform) {
95990
96408
  for (const entry of LEGACY_CODEX_COMPONENT_BINS) {
95991
96409
  const linkPath = join24(binDir, platform === "win32" ? `${entry.name}.cmd` : entry.name);
@@ -96041,7 +96459,7 @@ function isNodeErrorWithCode2(error51) {
96041
96459
  // packages/omo-codex/src/install/codex-cache-runtime-wrapper.ts
96042
96460
  import { join as join25 } from "node:path";
96043
96461
  var RUNTIME_WRAPPER_MARKER = "OMO_GENERATED_RUNTIME_WRAPPER";
96044
- function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96462
+ function posixRuntimeWrapper(binName, cliPath, codexHome, binDir, nodeCliPath) {
96045
96463
  const ulwLoopBin = toPosixPath2(join25(binDir, "omo-ulw-loop"));
96046
96464
  const nodeCli = escapePosixDoubleQuoted(toPosixPath2(nodeCliPath));
96047
96465
  const escapedCliPath = escapePosixDoubleQuoted(toPosixPath2(cliPath));
@@ -96051,6 +96469,8 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96051
96469
  "#!/bin/sh",
96052
96470
  `# ${RUNTIME_WRAPPER_MARKER}`,
96053
96471
  `export CODEX_HOME="\${CODEX_HOME:-${escapedCodexHome}}"`,
96472
+ `export OMO_INVOCATION_NAME=${binName}`,
96473
+ "export OMO_EDITION=codex",
96054
96474
  'if [ "$1" = "ulw-loop" ] && [ -x "' + escapedUlwLoopBin + '" ]; then',
96055
96475
  " shift",
96056
96476
  ' exec "' + escapedUlwLoopBin + '" ulw-loop "$@"',
@@ -96074,11 +96494,11 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96074
96494
  ` if [ -f "${nodeCli}" ] && command -v node >/dev/null 2>&1; then`,
96075
96495
  ` exec node "${nodeCli}" "$@"`,
96076
96496
  " fi",
96077
- ` 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`,
96497
+ ` 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`,
96078
96498
  " exit 127",
96079
96499
  "fi",
96080
96500
  `if [ ! -f "${escapedCliPath}" ]; then`,
96081
- ` echo "omo: runtime target missing at ${escapedCliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui" >&2`,
96501
+ ` echo "${binName}: runtime target missing at ${escapedCliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui" >&2`,
96082
96502
  " exit 1",
96083
96503
  "fi",
96084
96504
  `exec "$BUN_BINARY" "${escapedCliPath}" "$@"`,
@@ -96086,12 +96506,14 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96086
96506
  ].join(`
96087
96507
  `);
96088
96508
  }
96089
- function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96509
+ function windowsRuntimeWrapper(binName, cliPath, codexHome, binDir, nodeCliPath) {
96090
96510
  const ulwLoopBin = join25(binDir, "omo-ulw-loop.cmd");
96091
96511
  return [
96092
96512
  "@echo off",
96093
96513
  `rem ${RUNTIME_WRAPPER_MARKER}`,
96094
96514
  `if not defined CODEX_HOME set "CODEX_HOME=${codexHome}"`,
96515
+ `set "OMO_INVOCATION_NAME=${binName}"`,
96516
+ 'set "OMO_EDITION=codex"',
96095
96517
  ...windowsNodeDiscoveryLines(),
96096
96518
  `if "%~1"=="ulw-loop" if exist "${ulwLoopBin}" (`,
96097
96519
  " shift /1",
@@ -96109,11 +96531,11 @@ function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
96109
96531
  ` "%OMO_NODE_BINARY%" "${nodeCliPath}" %*`,
96110
96532
  " exit /b %ERRORLEVEL%",
96111
96533
  " )",
96112
- ` 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`,
96534
+ ` 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`,
96113
96535
  " exit /b 127",
96114
96536
  ")",
96115
96537
  `if not exist "${cliPath}" (`,
96116
- ` echo omo: runtime target missing at ${cliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui 1>&2`,
96538
+ ` echo ${binName}: runtime target missing at ${cliPath}; reinstall with: npx --yes lazycodex-ai@latest install --no-tui 1>&2`,
96117
96539
  " exit /b 1",
96118
96540
  ")",
96119
96541
  `"%BUN_BINARY%" "${cliPath}" %*`,
@@ -96129,7 +96551,14 @@ function escapePosixDoubleQuoted(value) {
96129
96551
  }
96130
96552
 
96131
96553
  // packages/omo-codex/src/install/codex-cache-bins.ts
96132
- var RESERVED_NESTED_BIN_NAMES = new Set(["omo", "lazycodex", "lazycodex-ai", "oh-my-opencode", "oh-my-openagent"]);
96554
+ var RESERVED_NESTED_BIN_NAMES = new Set([
96555
+ "omo",
96556
+ "omo-agent-toolkit",
96557
+ "lazycodex",
96558
+ "lazycodex-ai",
96559
+ "oh-my-opencode",
96560
+ "oh-my-openagent"
96561
+ ]);
96133
96562
  async function linkCachedPluginBins(input) {
96134
96563
  const binLinks = await discoverPackageBins(input.pluginRoot);
96135
96564
  const platform = input.platform ?? process.platform;
@@ -96159,20 +96588,26 @@ async function removeCachedManagedNpmBinShims(pluginRoot) {
96159
96588
  }
96160
96589
  async function linkRootRuntimeBin(input) {
96161
96590
  const cliPath = join26(input.repoRoot, "dist", "cli", "index.js");
96162
- if (!await isFile(cliPath))
96591
+ const platform = input.platform ?? process.platform;
96592
+ const legacyPath = join26(input.binDir, platform === "win32" ? "omo.cmd" : "omo");
96593
+ if (!await isFile(cliPath)) {
96594
+ await removeGeneratedRuntimeWrapper(legacyPath);
96163
96595
  return null;
96596
+ }
96597
+ const binName = "omo-agent-toolkit";
96164
96598
  const nodeCliPath = join26(input.repoRoot, "dist", "cli-node", "index.js");
96165
- const platform = input.platform ?? process.platform;
96166
96599
  await mkdir(input.binDir, { recursive: true });
96167
96600
  if (platform === "win32") {
96168
- const linkPath2 = join26(input.binDir, "omo.cmd");
96169
- await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
96170
- return { name: "omo", path: linkPath2, target: cliPath };
96601
+ const linkPath2 = join26(input.binDir, `${binName}.cmd`);
96602
+ await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(binName, cliPath, input.codexHome, input.binDir, nodeCliPath));
96603
+ await removeGeneratedRuntimeWrapper(legacyPath);
96604
+ return { name: binName, path: linkPath2, target: cliPath };
96171
96605
  }
96172
- const linkPath = join26(input.binDir, "omo");
96173
- await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
96606
+ const linkPath = join26(input.binDir, binName);
96607
+ await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(binName, cliPath, input.codexHome, input.binDir, nodeCliPath));
96174
96608
  await chmod(linkPath, 493);
96175
- return { name: "omo", path: linkPath, target: cliPath };
96609
+ await removeGeneratedRuntimeWrapper(legacyPath);
96610
+ return { name: binName, path: linkPath, target: cliPath };
96176
96611
  }
96177
96612
  async function linkCachedPluginBin(binDir, link, platform) {
96178
96613
  if (platform === "win32") {
@@ -96285,6 +96720,29 @@ async function replaceRuntimeWrapper(linkPath, content) {
96285
96720
  await rm3(linkPath, { force: true });
96286
96721
  await writeFile(linkPath, content);
96287
96722
  }
96723
+ async function removeGeneratedRuntimeWrapper(path6) {
96724
+ try {
96725
+ const entry = await lstat4(path6);
96726
+ if (!entry.isFile() && !entry.isSymbolicLink())
96727
+ return;
96728
+ const content = await readGeneratedWrapperContent(path6);
96729
+ if (content.includes(RUNTIME_WRAPPER_MARKER))
96730
+ await rm3(path6, { force: true });
96731
+ } catch (error51) {
96732
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
96733
+ return;
96734
+ throw error51;
96735
+ }
96736
+ }
96737
+ async function readGeneratedWrapperContent(path6) {
96738
+ try {
96739
+ return await readFile3(path6, "utf8");
96740
+ } catch (error51) {
96741
+ if (isNodeErrorWithCode(error51) && (error51.code === "ENOENT" || error51.code === "EISDIR"))
96742
+ return "";
96743
+ throw error51;
96744
+ }
96745
+ }
96288
96746
  async function existingNonRuntimeWrapper(path6) {
96289
96747
  try {
96290
96748
  const stat3 = await lstat4(path6);
@@ -96360,7 +96818,7 @@ async function copyBundledMcpRuntimeDists(input) {
96360
96818
  }
96361
96819
  }
96362
96820
  function resolveBundledMcpRuntimeArg(pluginRoot, arg) {
96363
- const runtime4 = BUNDLED_MCP_RUNTIMES.find((candidate) => candidate.sourceArg === arg);
96821
+ const runtime4 = BUNDLED_MCP_RUNTIMES.find((candidate2) => candidate2.sourceArg === arg);
96364
96822
  return runtime4 ? join27(pluginRoot, runtime4.destinationArg) : null;
96365
96823
  }
96366
96824
  async function copyBundledMcpRuntimeDist(pluginRoot, sourceRoot, runtime4) {
@@ -96436,9 +96894,9 @@ function findNewestCachedCodexComponentCli(input) {
96436
96894
  return null;
96437
96895
  const versions2 = readdirSync6(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionNames).reverse();
96438
96896
  for (const version2 of versions2) {
96439
- const candidate = resolveCachedCodexComponentCliPath(join28(versionsRoot, version2), input.componentName);
96440
- if (existsSync24(candidate))
96441
- return candidate;
96897
+ const candidate2 = resolveCachedCodexComponentCliPath(join28(versionsRoot, version2), input.componentName);
96898
+ if (existsSync24(candidate2))
96899
+ return candidate2;
96442
96900
  }
96443
96901
  return null;
96444
96902
  }
@@ -97404,8 +97862,8 @@ function findUnquotedCharacter(line, target, startIndex) {
97404
97862
  }
97405
97863
  return -1;
97406
97864
  }
97407
- function tomlPathMatches(candidate, target) {
97408
- return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
97865
+ function tomlPathMatches(candidate2, target) {
97866
+ return candidate2.length === target.length && candidate2.every((part, index) => part === target[index]);
97409
97867
  }
97410
97868
  function replaceTomlAssignmentValue(line, assignmentIndex, value) {
97411
97869
  const newline = line.endsWith(`
@@ -99984,13 +100442,13 @@ function processIsRunning(pid) {
99984
100442
  }
99985
100443
 
99986
100444
  // packages/omo-codex/src/install/codex-installer-bin-dir.ts
99987
- import { homedir as homedir4 } from "node:os";
100445
+ import { homedir as homedir5 } from "node:os";
99988
100446
  import { join as join48, resolve as resolve12 } from "node:path";
99989
100447
  function resolveCodexInstallerBinDir(input) {
99990
100448
  const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
99991
100449
  if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
99992
100450
  return resolve12(explicitBinDir.trim());
99993
- const homeDir = input.homeDir ?? homedir4();
100451
+ const homeDir = input.homeDir ?? homedir5();
99994
100452
  const defaultCodexHome = resolve12(homeDir, ".codex");
99995
100453
  const resolvedCodexHome = resolve12(input.codexHome);
99996
100454
  if (resolvedCodexHome !== defaultCodexHome)
@@ -99998,9 +100456,57 @@ function resolveCodexInstallerBinDir(input) {
99998
100456
  return resolve12(homeDir, ".local", "bin");
99999
100457
  }
100000
100458
 
100001
- // packages/omo-codex/src/install/codex-git-bash-hooks.ts
100002
- import { readFile as readFile20, writeFile as writeFile11 } from "node:fs/promises";
100459
+ // packages/omo-codex/src/install/codex-installed-bin-dir.ts
100460
+ import { readFile as readFile20, readdir as readdir11, writeFile as writeFile11 } from "node:fs/promises";
100003
100461
  import { join as join49 } from "node:path";
100462
+ var INSTALLED_BIN_DIR_MANIFEST = ".installed-bin-dir.json";
100463
+ async function writeInstalledCodexBinDir(input) {
100464
+ await writeFile11(join49(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
100465
+ `);
100466
+ }
100467
+ async function readInstalledCodexBinDir(codexHome) {
100468
+ for (const manifestPath of await installedBinDirManifestPaths(codexHome)) {
100469
+ const binDir = await readBinDirFromManifest(manifestPath);
100470
+ if (binDir !== null)
100471
+ return binDir;
100472
+ }
100473
+ return null;
100474
+ }
100475
+ async function installedBinDirManifestPaths(codexHome) {
100476
+ const paths2 = [
100477
+ join49(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_BIN_DIR_MANIFEST)
100478
+ ];
100479
+ const versionRoot = join49(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
100480
+ const entries = await readdir11(versionRoot, { withFileTypes: true }).catch(() => null);
100481
+ if (entries !== null) {
100482
+ for (const entry of entries) {
100483
+ if (entry.isDirectory())
100484
+ paths2.push(join49(versionRoot, entry.name, INSTALLED_BIN_DIR_MANIFEST));
100485
+ }
100486
+ }
100487
+ return paths2;
100488
+ }
100489
+ async function readBinDirFromManifest(manifestPath) {
100490
+ const raw = await readFile20(manifestPath, "utf8").catch(() => null);
100491
+ if (raw === null)
100492
+ return null;
100493
+ let parsed;
100494
+ try {
100495
+ parsed = JSON.parse(raw);
100496
+ } catch {
100497
+ return null;
100498
+ }
100499
+ if (!isPlainRecord4(parsed))
100500
+ return null;
100501
+ const binDir = parsed.binDir;
100502
+ if (typeof binDir !== "string" || binDir.trim().length === 0)
100503
+ return null;
100504
+ return binDir.trim();
100505
+ }
100506
+
100507
+ // packages/omo-codex/src/install/codex-git-bash-hooks.ts
100508
+ import { readFile as readFile21, writeFile as writeFile12 } from "node:fs/promises";
100509
+ import { join as join50 } from "node:path";
100004
100510
  var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
100005
100511
  "./hooks/pre-tool-use-recommending-git-bash-mcp.json",
100006
100512
  "./hooks/post-compact-resetting-git-bash-mcp-reminder.json"
@@ -100008,22 +100514,22 @@ var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
100008
100514
  async function removeGitBashHooksOffWindows(input) {
100009
100515
  if (input.platform === "win32")
100010
100516
  return;
100011
- const manifestPath = join49(input.pluginRoot, ".codex-plugin", "plugin.json");
100012
- const parsed = JSON.parse(await readFile20(manifestPath, "utf8"));
100517
+ const manifestPath = join50(input.pluginRoot, ".codex-plugin", "plugin.json");
100518
+ const parsed = JSON.parse(await readFile21(manifestPath, "utf8"));
100013
100519
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.hooks))
100014
100520
  return;
100015
100521
  const hooks = parsed.hooks.filter((hook) => typeof hook !== "string" || !WINDOWS_ONLY_GIT_BASH_HOOKS.has(hook));
100016
100522
  if (hooks.length === parsed.hooks.length)
100017
100523
  return;
100018
- await writeFile11(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
100524
+ await writeFile12(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
100019
100525
  `);
100020
100526
  }
100021
100527
 
100022
100528
  // packages/omo-codex/src/install/omo-sot-migration.ts
100023
- import { join as join50 } from "node:path";
100529
+ import { join as join51 } from "node:path";
100024
100530
  async function seedAndMigrateOmoSot(input) {
100025
100531
  const commandEnv = { ...input.env };
100026
- const scriptPath = join50(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
100532
+ const scriptPath = join51(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
100027
100533
  try {
100028
100534
  await input.runCommand(process.execPath, [scriptPath, "--seed"], {
100029
100535
  cwd: input.repoRoot,
@@ -100038,7 +100544,7 @@ async function seedAndMigrateOmoSot(input) {
100038
100544
 
100039
100545
  // packages/omo-codex/src/install/install-ast-grep-sg.ts
100040
100546
  init_src2();
100041
- import { join as join51 } from "node:path";
100547
+ import { join as join52 } from "node:path";
100042
100548
  function describeResult(result) {
100043
100549
  if (result.kind === "succeeded")
100044
100550
  return null;
@@ -100052,7 +100558,7 @@ async function installAstGrepForCodex(options) {
100052
100558
  return;
100053
100559
  const platform = options.platform ?? process.platform;
100054
100560
  const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
100055
- const skillDir = join51(plugin.path, "skills", "ast-grep");
100561
+ const skillDir = join52(plugin.path, "skills", "ast-grep");
100056
100562
  const installer = options.installer ?? runAstGrepSkillInstall;
100057
100563
  try {
100058
100564
  const result = await installer({ platform, skillDir, targetDir });
@@ -100086,7 +100592,7 @@ async function runCodexInstaller(options = {}) {
100086
100592
  const env3 = options.env ?? process.env;
100087
100593
  const platform = options.platform ?? process.platform;
100088
100594
  const repoRoot = resolve13(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env3 }));
100089
- const codexHome = resolve13(options.codexHome ?? env3.CODEX_HOME ?? join54(homedir5(), ".codex"));
100595
+ const codexHome = resolve13(options.codexHome ?? env3.CODEX_HOME ?? join55(homedir6(), ".codex"));
100090
100596
  const projectDirectory = resolve13(options.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd());
100091
100597
  const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env3 });
100092
100598
  const runCommand = options.runCommand ?? defaultRunCommand;
@@ -100103,9 +100609,9 @@ async function runCodexInstaller(options = {}) {
100103
100609
  if (!gitBashResolution.found) {
100104
100610
  throw new Error(gitBashResolution.installHint);
100105
100611
  }
100106
- const codexPackageRoot = join54(repoRoot, "packages", "omo-codex");
100612
+ const codexPackageRoot = join55(repoRoot, "packages", "omo-codex");
100107
100613
  const marketplace = await readMarketplace(repoRoot, {
100108
- marketplacePath: join54(codexPackageRoot, "marketplace.json")
100614
+ marketplacePath: join55(codexPackageRoot, "marketplace.json")
100109
100615
  });
100110
100616
  const distributionManifest = await readDistributionManifest(repoRoot);
100111
100617
  const installed = [];
@@ -100139,6 +100645,7 @@ async function runCodexInstaller(options = {}) {
100139
100645
  if (marketplace.name === "sisyphuslabs" && plugin.name === "omo") {
100140
100646
  await stampLazyCodexPluginVersion({ pluginRoot: plugin.path, version: version3 });
100141
100647
  await writeLazyCodexInstallSnapshot({ pluginRoot: plugin.path, distributionManifest });
100648
+ await writeInstalledCodexBinDir({ pluginRoot: plugin.path, binDir });
100142
100649
  await removeGitBashHooksOffWindows({ platform, pluginRoot: plugin.path });
100143
100650
  }
100144
100651
  const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path, platform });
@@ -100150,7 +100657,7 @@ async function runCodexInstaller(options = {}) {
100150
100657
  if (runtimeLink !== null)
100151
100658
  log4(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
100152
100659
  else
100153
- 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`);
100660
+ 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`);
100154
100661
  }
100155
100662
  pluginSources.push({ name: entry.name, sourcePath });
100156
100663
  installed.push(plugin);
@@ -100213,13 +100720,13 @@ async function runCodexInstaller(options = {}) {
100213
100720
  continue;
100214
100721
  log4(`Warning: deferred legacy Codex LSP daemon cleanup for v${cleanup.version}: ${cleanup.reason}`);
100215
100722
  }
100216
- const marketplaceRoot = join54(codexHome, "plugins", "cache", marketplace.name);
100723
+ const marketplaceRoot = join55(codexHome, "plugins", "cache", marketplace.name);
100217
100724
  await writeCachedMarketplaceManifest({
100218
100725
  marketplaceName: marketplace.name,
100219
100726
  marketplaceRoot,
100220
100727
  plugins: installed
100221
100728
  });
100222
- const configPath = join54(codexHome, "config.toml");
100729
+ const configPath = join55(codexHome, "config.toml");
100223
100730
  await updateCodexConfig({
100224
100731
  configPath,
100225
100732
  repoRoot: codexPackageRoot,
@@ -100280,7 +100787,7 @@ function findRepoRootFromImporter(importerDir) {
100280
100787
  for (let depth = 0;depth <= 7; depth += 1) {
100281
100788
  if (isRepoRootWithCodexPlugin(current))
100282
100789
  return current;
100283
- for (const wrapperPackageRoot of [join54(current, "node_modules", "oh-my-openagent"), join54(current, "oh-my-openagent")]) {
100790
+ for (const wrapperPackageRoot of [join55(current, "node_modules", "oh-my-openagent"), join55(current, "oh-my-openagent")]) {
100284
100791
  if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
100285
100792
  return wrapperPackageRoot;
100286
100793
  }
@@ -100298,7 +100805,7 @@ function findRepoRoot(input) {
100298
100805
  return findRepoRootFromImporter(input.importerDir);
100299
100806
  }
100300
100807
  function isRepoRootWithCodexPlugin(repoRoot) {
100301
- return existsSync28(join54(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
100808
+ return existsSync28(join55(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
100302
100809
  }
100303
100810
  function codexMarketplaceSource(marketplaceRoot) {
100304
100811
  return { sourceType: "local", source: marketplaceRoot };
@@ -100307,7 +100814,7 @@ function codexMarketplaceSource(marketplaceRoot) {
100307
100814
  init_bun_which_shim();
100308
100815
  import { execFile as execFile3 } from "node:child_process";
100309
100816
  import { existsSync as existsSync29 } from "node:fs";
100310
- import { homedir as homedir6 } from "node:os";
100817
+ import { homedir as homedir7 } from "node:os";
100311
100818
  import { posix as posix8, win32 as win324 } from "node:path";
100312
100819
  var CODEX_PATH_CHECK_LABEL = "codex (PATH)";
100313
100820
  var WINDOWS_START_APPS_ARGS = [
@@ -100318,7 +100825,7 @@ var WINDOWS_START_APPS_ARGS = [
100318
100825
  async function detectCodexInstallation(input = {}) {
100319
100826
  const platform = input.platform ?? process.platform;
100320
100827
  const env3 = input.env ?? process.env;
100321
- const homeDir = input.homeDir ?? homedir6();
100828
+ const homeDir = input.homeDir ?? homedir7();
100322
100829
  const exists6 = input.exists ?? existsSync29;
100323
100830
  const which2 = input.which ?? bunWhich;
100324
100831
  const checkedPaths = [CODEX_PATH_CHECK_LABEL];
@@ -100361,10 +100868,10 @@ function detectMacCodexInstallation(input) {
100361
100868
  return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop for macOS.");
100362
100869
  }
100363
100870
  async function detectWindowsCodexInstallation(input) {
100364
- for (const candidate of windowsCodexCliPaths(input.env)) {
100365
- input.checkedPaths.push(candidate);
100366
- if (input.exists(candidate))
100367
- return { found: true, source: "windows-standard-cli", path: candidate };
100871
+ for (const candidate2 of windowsCodexCliPaths(input.env)) {
100872
+ input.checkedPaths.push(candidate2);
100873
+ if (input.exists(candidate2))
100874
+ return { found: true, source: "windows-standard-cli", path: candidate2 };
100368
100875
  }
100369
100876
  input.checkedPaths.push("Windows Start Apps: Codex");
100370
100877
  const appId = await findWindowsCodexStartApp(input.runCommand);
@@ -100433,13 +100940,81 @@ function defaultRunCommand2(command, args) {
100433
100940
  });
100434
100941
  }
100435
100942
  // packages/omo-codex/src/install/codex-cleanup.ts
100436
- import { lstat as lstat13, readFile as readFile22, readdir as readdir11, rm as rm11, rmdir } from "node:fs/promises";
100437
- import { homedir as homedir7 } from "node:os";
100438
- import { isAbsolute as isAbsolute9, join as join56, relative as relative6, resolve as resolve15 } from "node:path";
100943
+ import { lstat as lstat14, readFile as readFile24, readdir as readdir13, rm as rm12, rmdir } from "node:fs/promises";
100944
+ import { homedir as homedir8 } from "node:os";
100945
+ import { isAbsolute as isAbsolute10, join as join58, relative as relative6, resolve as resolve16 } from "node:path";
100946
+
100947
+ // packages/omo-codex/src/install/codex-cleanup-bins.ts
100948
+ import { lstat as lstat12, readFile as readFile22, readdir as readdir12, readlink as readlink6, rm as rm11 } from "node:fs/promises";
100949
+ import { dirname as dirname18, isAbsolute as isAbsolute8, join as join56, resolve as resolve14 } from "node:path";
100950
+ var ROOT_RUNTIME_BIN_NAME = "omo";
100951
+ var MANAGED_CODEX_BIN_NAMES = new Set([
100952
+ ROOT_RUNTIME_BIN_NAME,
100953
+ "omo-codegraph",
100954
+ "omo-comment-checker",
100955
+ "omo-git-bash-hook",
100956
+ "omo-lsp",
100957
+ "omo-rules",
100958
+ "omo-start-work-continuation",
100959
+ "omo-telemetry",
100960
+ "omo-ultrawork",
100961
+ "omo-ulw-loop",
100962
+ "lazycodex-executor-verify",
100963
+ "ulw",
100964
+ "ulw-loop",
100965
+ ...LEGACY_CODEX_COMPONENT_BIN_NAMES
100966
+ ]);
100967
+ async function removeManagedCodexBins(binDir, platform) {
100968
+ const entries = await readdir12(binDir, { withFileTypes: true }).catch((error51) => {
100969
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
100970
+ return null;
100971
+ throw error51;
100972
+ });
100973
+ if (entries === null)
100974
+ return [];
100975
+ const removed2 = [];
100976
+ for (const entry of entries) {
100977
+ const binName = managedBinNameForEntry2(entry.name, platform);
100978
+ if (binName === null || !MANAGED_CODEX_BIN_NAMES.has(binName))
100979
+ continue;
100980
+ const linkPath = join56(binDir, entry.name);
100981
+ if (await isManagedCodexBin(linkPath, platform, binName)) {
100982
+ await rm11(linkPath, { force: true });
100983
+ removed2.push(linkPath);
100984
+ }
100985
+ }
100986
+ return removed2;
100987
+ }
100988
+ function managedBinNameForEntry2(entryName, platform) {
100989
+ if (platform !== "win32")
100990
+ return entryName;
100991
+ const normalizedEntryName = entryName.toLowerCase();
100992
+ return normalizedEntryName.endsWith(".cmd") ? normalizedEntryName.slice(0, -".cmd".length) : null;
100993
+ }
100994
+ async function isManagedCodexBin(linkPath, platform, binName) {
100995
+ const entryStat = await lstat12(linkPath).catch((error51) => {
100996
+ if (isNodeErrorWithCode(error51) && error51.code === "ENOENT")
100997
+ return null;
100998
+ throw error51;
100999
+ });
101000
+ if (entryStat === null)
101001
+ return false;
101002
+ if (entryStat.isSymbolicLink()) {
101003
+ if (platform === "win32")
101004
+ return false;
101005
+ const linkTarget = await readlink6(linkPath);
101006
+ const target = isAbsolute8(linkTarget) ? linkTarget : resolve14(dirname18(linkPath), linkTarget);
101007
+ return isManagedComponentBinTarget(target) || isLegacyCodexBinTarget(binName, target);
101008
+ }
101009
+ if (!entryStat.isFile())
101010
+ return false;
101011
+ const content = await readFile22(linkPath, "utf8");
101012
+ return content.includes(RUNTIME_WRAPPER_MARKER) || content.includes(COMMAND_SHIM_MARKER);
101013
+ }
100439
101014
 
100440
101015
  // packages/omo-codex/src/install/codex-cleanup-config.ts
100441
- import { lstat as lstat12, mkdir as mkdir8, readFile as readFile21, writeFile as writeFile12 } from "node:fs/promises";
100442
- import { dirname as dirname18 } from "node:path";
101016
+ import { lstat as lstat13, mkdir as mkdir8, readFile as readFile23, writeFile as writeFile13 } from "node:fs/promises";
101017
+ import { dirname as dirname19 } from "node:path";
100443
101018
  var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
100444
101019
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE2 = ["codex-ultrawork-reviewer"];
100445
101020
  var CURRENT_MANAGED_CODEX_AGENT_NAMES2 = [
@@ -100471,14 +101046,14 @@ function cleanupCodexLightConfigText(config3) {
100471
101046
  async function cleanupCodexConfig(configPath, now) {
100472
101047
  if (!await configExists(configPath))
100473
101048
  return { changed: false };
100474
- const original = await readFile21(configPath, "utf8");
101049
+ const original = await readFile23(configPath, "utf8");
100475
101050
  const next = cleanupCodexLightConfigText(original);
100476
101051
  if (next === original)
100477
101052
  return { changed: false };
100478
101053
  const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
100479
- await mkdir8(dirname18(configPath), { recursive: true });
100480
- await writeFile12(backupPath, original);
100481
- await writeFile12(configPath, `${next.trimEnd()}
101054
+ await mkdir8(dirname19(configPath), { recursive: true });
101055
+ await writeFile13(backupPath, original);
101056
+ await writeFile13(configPath, `${next.trimEnd()}
100482
101057
  `);
100483
101058
  return { changed: true, backupPath };
100484
101059
  }
@@ -100540,7 +101115,7 @@ function formatBackupTimestamp2(date5) {
100540
101115
  }
100541
101116
  async function configExists(path6) {
100542
101117
  try {
100543
- await lstat12(path6);
101118
+ await lstat13(path6);
100544
101119
  return true;
100545
101120
  } catch (error51) {
100546
101121
  if (nodeErrorCode5(error51) === "ENOENT")
@@ -100555,24 +101130,28 @@ function nodeErrorCode5(error51) {
100555
101130
  }
100556
101131
 
100557
101132
  // packages/omo-codex/src/install/codex-cleanup-safety.ts
100558
- import { dirname as dirname19, isAbsolute as isAbsolute8, join as join55, relative as relative5, resolve as resolve14 } from "node:path";
101133
+ import { dirname as dirname20, isAbsolute as isAbsolute9, join as join57, relative as relative5, resolve as resolve15 } from "node:path";
101134
+ function codexHomeResolvesToFilesystemRoot(codexHome) {
101135
+ const resolved = resolve15(codexHome);
101136
+ return dirname20(resolved) === resolved;
101137
+ }
100559
101138
  function validateManagedCleanupTarget(input) {
100560
- if (!isAbsolute8(input.path))
101139
+ if (!isAbsolute9(input.path))
100561
101140
  return skipped(input.path, "outside managed Codex cleanup scope");
100562
- const codexHome = resolve14(input.codexHome);
100563
- if (dirname19(codexHome) === codexHome)
101141
+ const codexHome = resolve15(input.codexHome);
101142
+ if (codexHomeResolvesToFilesystemRoot(codexHome))
100564
101143
  return skipped(input.path, "Codex home resolves to a filesystem root");
100565
- const target = resolve14(input.path);
101144
+ const target = resolve15(input.path);
100566
101145
  if (!isWithinDirectory(codexHome, target))
100567
101146
  return skipped(input.path, "outside managed Codex cleanup scope");
100568
101147
  if (target === codexHome)
100569
101148
  return skipped(input.path, "outside managed Codex cleanup scope");
100570
101149
  const exactManagedRoots = new Set([
100571
- resolve14(join55(codexHome, "plugins", "cache", "sisyphuslabs")),
100572
- resolve14(join55(codexHome, ".tmp", "marketplaces", "sisyphuslabs")),
100573
- resolve14(join55(codexHome, "runtime", "ast-grep")),
100574
- resolve14(join55(codexHome, "runtime", "node")),
100575
- resolve14(join55(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap"))
101150
+ resolve15(join57(codexHome, "plugins", "cache", "sisyphuslabs")),
101151
+ resolve15(join57(codexHome, ".tmp", "marketplaces", "sisyphuslabs")),
101152
+ resolve15(join57(codexHome, "runtime", "ast-grep")),
101153
+ resolve15(join57(codexHome, "runtime", "node")),
101154
+ resolve15(join57(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap"))
100576
101155
  ]);
100577
101156
  if (exactManagedRoots.has(target))
100578
101157
  return null;
@@ -100582,7 +101161,7 @@ function validateManagedCleanupTarget(input) {
100582
101161
  }
100583
101162
  function isWithinDirectory(parent, child) {
100584
101163
  const relativePath = relative5(parent, child);
100585
- return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute8(relativePath);
101164
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute9(relativePath);
100586
101165
  }
100587
101166
  function isManagedBootstrapDriftPath(codexHome, target) {
100588
101167
  const relativePath = relative5(codexHome, target);
@@ -100602,8 +101181,9 @@ function skipped(path6, reason) {
100602
101181
  var INSTALLED_AGENTS_MANIFEST = ".installed-agents.json";
100603
101182
  async function cleanupCodexLight(input = {}) {
100604
101183
  const env3 = input.env ?? process.env;
100605
- const codexHome = resolve15(input.codexHome ?? env3.CODEX_HOME ?? join56(homedir7(), ".codex"));
100606
- const configPath = join56(codexHome, "config.toml");
101184
+ const codexHome = resolve16(input.codexHome ?? env3.CODEX_HOME ?? join58(homedir8(), ".codex"));
101185
+ const configPath = join58(codexHome, "config.toml");
101186
+ const installedBinDir = await readInstalledCodexBinDir(codexHome);
100607
101187
  const agentPaths = await collectInstalledAgentPaths(codexHome, configPath);
100608
101188
  const configCleanup = await cleanupCodexConfig(configPath, input.now);
100609
101189
  const agentCleanup = await removeManifestListedAgentLinks(codexHome, agentPaths);
@@ -100619,6 +101199,12 @@ async function cleanupCodexLight(input = {}) {
100619
101199
  }
100620
101200
  }
100621
101201
  await pruneEmptyRuntimeDirBestEffort(codexHome);
101202
+ const binDir = resolveCodexInstallerBinDir({
101203
+ binDir: firstConfiguredPath(input.binDir, env3.CODEX_LOCAL_BIN_DIR, installedBinDir),
101204
+ codexHome,
101205
+ env: env3
101206
+ });
101207
+ const removedBinLinks = codexHomeResolvesToFilesystemRoot(codexHome) ? [] : await removeManagedCodexBins(binDir, input.platform ?? process.platform);
100622
101208
  const projectDirectory = input.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd();
100623
101209
  const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
100624
101210
  startDirectory: projectDirectory,
@@ -100637,36 +101223,44 @@ async function cleanupCodexLight(input = {}) {
100637
101223
  skippedPaths,
100638
101224
  removedAgentLinks: agentCleanup.removed,
100639
101225
  skippedAgentLinks: agentCleanup.skipped,
101226
+ removedBinLinks,
100640
101227
  projectCleanup
100641
101228
  };
100642
101229
  }
101230
+ function firstConfiguredPath(...values) {
101231
+ for (const value of values) {
101232
+ if (typeof value === "string" && value.trim().length > 0)
101233
+ return value;
101234
+ }
101235
+ return;
101236
+ }
100643
101237
  function managedGlobalStatePaths(codexHome) {
100644
101238
  return [
100645
- join56(codexHome, "plugins", "cache", "sisyphuslabs"),
100646
- join56(codexHome, ".tmp", "marketplaces", "sisyphuslabs"),
100647
- join56(codexHome, "runtime", "ast-grep"),
100648
- join56(codexHome, "runtime", "node"),
100649
- join56(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap")
101239
+ join58(codexHome, "plugins", "cache", "sisyphuslabs"),
101240
+ join58(codexHome, ".tmp", "marketplaces", "sisyphuslabs"),
101241
+ join58(codexHome, "runtime", "ast-grep"),
101242
+ join58(codexHome, "runtime", "node"),
101243
+ join58(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap")
100650
101244
  ];
100651
101245
  }
100652
101246
  var BOOTSTRAP_DATA_GLOB_MAX_DEPTH = 5;
100653
101247
  async function collectBootstrapDataDirsByGlob(codexHome) {
100654
101248
  const results = [];
100655
- await walkForManagedBootstrapDirs(join56(codexHome, "plugins"), 0, results);
101249
+ await walkForManagedBootstrapDirs(join58(codexHome, "plugins"), 0, results);
100656
101250
  return results;
100657
101251
  }
100658
101252
  async function walkForManagedBootstrapDirs(directory, depth, results) {
100659
101253
  if (depth > BOOTSTRAP_DATA_GLOB_MAX_DEPTH)
100660
101254
  return;
100661
- const entries = await readdir11(directory, { withFileTypes: true }).catch(() => null);
101255
+ const entries = await readdir13(directory, { withFileTypes: true }).catch(() => null);
100662
101256
  if (entries === null)
100663
101257
  return;
100664
101258
  for (const entry of entries) {
100665
101259
  if (!entry.isDirectory())
100666
101260
  continue;
100667
- const childPath = join56(directory, entry.name);
101261
+ const childPath = join58(directory, entry.name);
100668
101262
  if (isManagedBootstrapOwnerName(entry.name)) {
100669
- const bootstrapDir = join56(childPath, "bootstrap");
101263
+ const bootstrapDir = join58(childPath, "bootstrap");
100670
101264
  if (await exists6(bootstrapDir))
100671
101265
  results.push(bootstrapDir);
100672
101266
  continue;
@@ -100690,9 +101284,9 @@ async function removeManagedPathBestEffort(path6, seams) {
100690
101284
  }
100691
101285
  async function attemptRemove(path6) {
100692
101286
  try {
100693
- if (await lstat13(path6).catch(() => null) === null)
101287
+ if (await lstat14(path6).catch(() => null) === null)
100694
101288
  return false;
100695
- await rm11(path6, { recursive: true, force: true });
101289
+ await rm12(path6, { recursive: true, force: true });
100696
101290
  return true;
100697
101291
  } catch {
100698
101292
  return false;
@@ -100700,7 +101294,7 @@ async function attemptRemove(path6) {
100700
101294
  }
100701
101295
  async function pruneEmptyRuntimeDirBestEffort(codexHome) {
100702
101296
  try {
100703
- await rmdir(join56(codexHome, "runtime"));
101297
+ await rmdir(join58(codexHome, "runtime"));
100704
101298
  } catch (error51) {
100705
101299
  if (isExpectedRuntimePruneFailure(error51))
100706
101300
  return;
@@ -100712,14 +101306,14 @@ function isExpectedRuntimePruneFailure(error51) {
100712
101306
  }
100713
101307
  async function collectInstalledAgentPaths(codexHome, configPath) {
100714
101308
  const manifestPaths = [
100715
- join56(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
101309
+ join58(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
100716
101310
  ];
100717
- const versionRoot = join56(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
101311
+ const versionRoot = join58(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
100718
101312
  if (await exists6(versionRoot)) {
100719
- const entries = await readdir11(versionRoot, { withFileTypes: true });
101313
+ const entries = await readdir13(versionRoot, { withFileTypes: true });
100720
101314
  for (const entry of entries) {
100721
101315
  if (entry.isDirectory())
100722
- manifestPaths.push(join56(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
101316
+ manifestPaths.push(join58(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
100723
101317
  }
100724
101318
  }
100725
101319
  const paths2 = new Set;
@@ -100736,19 +101330,19 @@ async function collectInstalledAgentPaths(codexHome, configPath) {
100736
101330
  async function readManagedAgentPathsFromConfig(codexHome, configPath) {
100737
101331
  if (!await exists6(configPath))
100738
101332
  return [];
100739
- const config3 = await readFile22(configPath, "utf8");
100740
- return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config3.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join56(codexHome, "agents", `${agentName}.toml`));
101333
+ const config3 = await readFile24(configPath, "utf8");
101334
+ return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config3.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join58(codexHome, "agents", `${agentName}.toml`));
100741
101335
  }
100742
101336
  async function readInstalledAgentManifest(manifestPath) {
100743
101337
  if (!await exists6(manifestPath))
100744
101338
  return [];
100745
- const parsed = JSON.parse(await readFile22(manifestPath, "utf8"));
101339
+ const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
100746
101340
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.agents))
100747
101341
  return [];
100748
101342
  return parsed.agents.filter((path6) => typeof path6 === "string");
100749
101343
  }
100750
101344
  async function removeManifestListedAgentLinks(codexHome, paths2) {
100751
- const agentsDir = join56(codexHome, "agents");
101345
+ const agentsDir = join58(codexHome, "agents");
100752
101346
  const removed2 = [];
100753
101347
  const skipped2 = [];
100754
101348
  for (const path6 of paths2) {
@@ -100763,16 +101357,16 @@ async function removeManifestListedAgentLinks(codexHome, paths2) {
100763
101357
  skipped2.push(path6);
100764
101358
  continue;
100765
101359
  }
100766
- await rm11(path6, { force: true });
101360
+ await rm12(path6, { force: true });
100767
101361
  removed2.push(path6);
100768
101362
  }
100769
101363
  return { removed: removed2, skipped: skipped2 };
100770
101364
  }
100771
101365
  function isSafeManagedAgentPath(agentsDir, path6) {
100772
- if (!isAbsolute9(path6))
101366
+ if (!isAbsolute10(path6))
100773
101367
  return false;
100774
101368
  const relativePath = relative6(agentsDir, path6);
100775
- if (relativePath === "" || relativePath.startsWith("..") || isAbsolute9(relativePath))
101369
+ if (relativePath === "" || relativePath.startsWith("..") || isAbsolute10(relativePath))
100776
101370
  return false;
100777
101371
  const fileName = relativePath.split(/[\\/]/).pop();
100778
101372
  if (fileName === undefined)
@@ -100784,7 +101378,7 @@ async function exists6(path6) {
100784
101378
  }
100785
101379
  async function maybeLstat2(path6) {
100786
101380
  try {
100787
- return await lstat13(path6);
101381
+ return await lstat14(path6);
100788
101382
  } catch (error51) {
100789
101383
  if (nodeErrorCode6(error51) === "ENOENT")
100790
101384
  return null;
@@ -100800,52 +101394,162 @@ function nodeErrorCode6(error51) {
100800
101394
  var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
100801
101395
  // packages/omo-senpi/src/install/install-senpi.ts
100802
101396
  import { execFile as execFile4 } from "node:child_process";
100803
- import { constants as constants7, existsSync as existsSync30 } from "node:fs";
100804
- import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile23, rename as rename5, writeFile as writeFile13 } from "node:fs/promises";
100805
- import { homedir as homedir8 } from "node:os";
100806
- import { dirname as dirname20, join as join57, resolve as resolve16 } from "node:path";
101397
+ import { createHash as createHash5 } from "node:crypto";
101398
+ import { constants as constants8, existsSync as existsSync30 } from "node:fs";
101399
+ import { access as access2, readFile as readFile26, stat as stat6 } from "node:fs/promises";
101400
+ import { homedir as homedir9 } from "node:os";
101401
+ import { dirname as dirname22, join as join60, resolve as resolve18 } from "node:path";
100807
101402
  import { fileURLToPath } from "node:url";
100808
101403
  import { promisify as promisify2 } from "node:util";
101404
+
101405
+ // packages/omo-senpi/src/install/senpi-settings.ts
101406
+ import { constants as constants7 } from "node:fs";
101407
+ import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile25, rename as rename5, writeFile as writeFile14 } from "node:fs/promises";
101408
+ import { dirname as dirname21, join as join59, resolve as resolve17 } from "node:path";
101409
+ var OMO_SENPI_PACKAGE_NAME = "@code-yeongyu/omo-senpi";
101410
+ var LEGACY_BUILTIN_SHADOW_PACKAGES = [
101411
+ join59("packages", "pi-goal"),
101412
+ join59("packages", "pi-webfetch")
101413
+ ];
101414
+ async function readSettings(settingsPath) {
101415
+ let raw;
101416
+ try {
101417
+ raw = await readFile25(settingsPath, "utf8");
101418
+ } catch (error51) {
101419
+ if (isErrno(error51, "ENOENT"))
101420
+ return {};
101421
+ throw error51;
101422
+ }
101423
+ const parsed = JSON.parse(raw);
101424
+ if (!isRecord10(parsed))
101425
+ throw new Error(`${settingsPath} must contain a JSON object`);
101426
+ return parsed;
101427
+ }
101428
+ function readPackages(settings) {
101429
+ const packages = settings.packages;
101430
+ if (packages === undefined)
101431
+ return [];
101432
+ if (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string")) {
101433
+ throw new Error("Senpi settings packages must be an array of strings");
101434
+ }
101435
+ return packages;
101436
+ }
101437
+ function dedupePackages(packages) {
101438
+ return [...new Set(packages)];
101439
+ }
101440
+ function removeLegacyBuiltinShadows(packages, repoRoot, agentDir) {
101441
+ const shadowPaths = new Set(LEGACY_BUILTIN_SHADOW_PACKAGES.map((path6) => resolve17(repoRoot, path6)));
101442
+ return packages.filter((entry) => !shadowPaths.has(resolve17(agentDir, entry)));
101443
+ }
101444
+ async function removeSupersededOmoPackages(packages, currentPluginPath, agentDir) {
101445
+ const currentPath = resolve17(currentPluginPath);
101446
+ const entries = await Promise.all(packages.map(async (entry) => {
101447
+ const packagePath = resolve17(agentDir, entry);
101448
+ if (packagePath === currentPath)
101449
+ return currentPath;
101450
+ return await readPackageName(packagePath) === OMO_SENPI_PACKAGE_NAME ? undefined : entry;
101451
+ }));
101452
+ return entries.filter((entry) => entry !== undefined);
101453
+ }
101454
+ async function writeSettingsAtomically(settingsPath, settings) {
101455
+ await mkdir9(dirname21(settingsPath), { recursive: true });
101456
+ const backupPath = await nextBackupPath(settingsPath);
101457
+ if (await fileExists(settingsPath)) {
101458
+ await copyFile3(settingsPath, backupPath);
101459
+ } else {
101460
+ await writeFile14(backupPath, `{}
101461
+ `, "utf8");
101462
+ }
101463
+ const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
101464
+ await writeFile14(tempPath, `${JSON.stringify(settings, null, 2)}
101465
+ `, "utf8");
101466
+ await rename5(tempPath, settingsPath);
101467
+ return backupPath;
101468
+ }
101469
+ async function nextBackupPath(settingsPath) {
101470
+ for (let index = 0;index < 1000; index += 1) {
101471
+ const suffix = index === 0 ? "" : `-${index}`;
101472
+ const candidate2 = `${settingsPath}.${timestampForBackup()}${suffix}.backup`;
101473
+ if (!await fileExists(candidate2))
101474
+ return candidate2;
101475
+ }
101476
+ throw new Error(`Unable to allocate backup path for ${settingsPath}`);
101477
+ }
101478
+ function timestampForBackup() {
101479
+ return new Date().toISOString().replace(/[-:.]/g, "");
101480
+ }
101481
+ function isRecord10(value) {
101482
+ return typeof value === "object" && value !== null && !Array.isArray(value);
101483
+ }
101484
+ async function readPackageName(packagePath) {
101485
+ let raw;
101486
+ try {
101487
+ raw = await readFile25(join59(packagePath, "package.json"), "utf8");
101488
+ } catch (error51) {
101489
+ if (isErrno(error51, "ENOENT") || isErrno(error51, "ENOTDIR"))
101490
+ return;
101491
+ throw error51;
101492
+ }
101493
+ const parsed = JSON.parse(raw);
101494
+ return isRecord10(parsed) && typeof parsed.name === "string" ? parsed.name : undefined;
101495
+ }
101496
+ async function fileExists(path6) {
101497
+ try {
101498
+ await access(path6, constants7.F_OK);
101499
+ return true;
101500
+ } catch (error51) {
101501
+ if (isErrno(error51, "ENOENT"))
101502
+ return false;
101503
+ throw error51;
101504
+ }
101505
+ }
101506
+ function isErrno(error51, code) {
101507
+ return error51 instanceof Error && "code" in error51 && error51.code === code;
101508
+ }
101509
+
101510
+ // packages/omo-senpi/src/install/install-senpi.ts
100809
101511
  var execFileAsync2 = promisify2(execFile4);
100810
101512
  var REQUIRED_PLUGIN_ARTIFACTS = [
100811
- join57("extensions", "omo.js"),
100812
- join57("skills", "ast-grep", "SKILL.md"),
100813
- join57("skills", "coding-agent-sessions", "SKILL.md"),
100814
- join57("skills", "debugging", "SKILL.md"),
100815
- join57("skills", "frontend", "SKILL.md"),
100816
- join57("skills", "git-master", "SKILL.md"),
100817
- join57("skills", "init-deep", "SKILL.md"),
100818
- join57("skills", "lsp-setup", "SKILL.md"),
100819
- join57("skills", "programming", "SKILL.md"),
100820
- join57("skills", "refactor", "SKILL.md"),
100821
- join57("skills", "remove-ai-slops", "SKILL.md"),
100822
- join57("skills", "review-work", "SKILL.md"),
100823
- join57("skills", "start-work", "SKILL.md"),
100824
- join57("skills", "ultimate-browsing", "SKILL.md"),
100825
- join57("skills", "ultrawork", "SKILL.md"),
100826
- join57("skills", "ulw-loop", "SKILL.md"),
100827
- join57("skills", "ulw-plan", "SKILL.md"),
100828
- join57("skills", "ulw-research", "SKILL.md"),
100829
- join57("skills", "visual-qa", "SKILL.md"),
100830
- join57("runtime", "lsp-daemon", "dist", "cli.js"),
100831
- join57("runtime", "lsp-daemon", "dist", "index.js"),
100832
- join57("runtime", "lsp-daemon", "dist", "index.d.ts"),
100833
- join57("runtime", "lsp-daemon", "dist", "daemon-client.js"),
100834
- join57("runtime", "lsp-daemon", "dist", "daemon-client.d.ts"),
100835
- join57("runtime", "lsp-daemon", "dist", "package.json"),
100836
- join57("runtime", "lsp-daemon", "dist", ".omo-runtime-manifest.json"),
100837
- join57("scripts", "install.mjs")
100838
- ];
100839
- var LEGACY_BUILTIN_SHADOW_PACKAGES = [
100840
- join57("packages", "pi-goal"),
100841
- join57("packages", "pi-webfetch")
101513
+ join60("extensions", "omo.js"),
101514
+ join60("extensions", "reflection-persona.md"),
101515
+ join60("skills", "ast-grep", "SKILL.md"),
101516
+ join60("skills", "coding-agent-sessions", "SKILL.md"),
101517
+ join60("skills", "debugging", "SKILL.md"),
101518
+ join60("skills", "frontend", "SKILL.md"),
101519
+ join60("skills", "git-master", "SKILL.md"),
101520
+ join60("skills", "init-deep", "SKILL.md"),
101521
+ join60("skills", "lsp-setup", "SKILL.md"),
101522
+ join60("skills", "programming", "SKILL.md"),
101523
+ join60("skills", "refactor", "SKILL.md"),
101524
+ join60("skills", "remove-ai-slops", "SKILL.md"),
101525
+ join60("skills", "review-work", "SKILL.md"),
101526
+ join60("skills", "start-work", "SKILL.md"),
101527
+ join60("skills", "ultimate-browsing", "SKILL.md"),
101528
+ join60("skills", "ultrawork", "SKILL.md"),
101529
+ join60("skills", "ulw-loop", "SKILL.md"),
101530
+ join60("skills", "ulw-plan", "SKILL.md"),
101531
+ join60("skills", "ulw-research", "SKILL.md"),
101532
+ join60("skills", "visual-qa", "SKILL.md"),
101533
+ join60("runtime", "ast-grep-mcp", "cli.js"),
101534
+ join60("runtime", "agent-toolkit", "cli.js"),
101535
+ join60("runtime", "agent-toolkit", "ulw-loop", "cli.js"),
101536
+ join60("runtime", "agent-toolkit", "omo-agent-toolkit"),
101537
+ join60("runtime", "agent-toolkit", "omo-agent-toolkit.cmd"),
101538
+ join60("runtime", "lsp-daemon", "dist", "cli.js"),
101539
+ join60("runtime", "lsp-daemon", "dist", "index.js"),
101540
+ join60("runtime", "lsp-daemon", "dist", "index.d.ts"),
101541
+ join60("runtime", "lsp-daemon", "dist", "daemon-client.js"),
101542
+ join60("runtime", "lsp-daemon", "dist", "daemon-client.d.ts"),
101543
+ join60("runtime", "lsp-daemon", "dist", "package.json"),
101544
+ join60("runtime", "lsp-daemon", "dist", ".omo-runtime-manifest.json"),
101545
+ join60("scripts", "install.mjs")
100842
101546
  ];
100843
101547
  async function runSenpiInstaller(options = {}) {
100844
101548
  const context = resolveInstallContext(options);
100845
101549
  await ensurePluginArtifacts(context);
100846
101550
  const settings = await readSettings(context.settingsPath);
100847
101551
  const before = JSON.stringify(settings);
100848
- const packages = removeLegacyBuiltinShadows(dedupePackages(readPackages(settings)), context.repoRoot, context.agentDir);
101552
+ const packages = dedupePackages(await removeSupersededOmoPackages(removeLegacyBuiltinShadows(dedupePackages(readPackages(settings)), context.repoRoot, context.agentDir), context.pluginPath, context.agentDir));
100849
101553
  if (!packages.includes(context.pluginPath))
100850
101554
  packages.push(context.pluginPath);
100851
101555
  settings.packages = packages;
@@ -100863,121 +101567,113 @@ async function runSenpiInstaller(options = {}) {
100863
101567
  function resolveInstallContext(options) {
100864
101568
  const env3 = options.env ?? process.env;
100865
101569
  const allowBuild = options.pluginPath === undefined;
100866
- const repoRoot = resolve16(options.repoRoot ?? (allowBuild ? findRepoRoot2(dirname20(fileURLToPath(import.meta.url))) : dirname20(resolve16(options.pluginPath))));
100867
- const agentDir = resolve16(options.agentDir ?? env3.SENPI_CODING_AGENT_DIR ?? join57(homedir8(), ".senpi", "agent"));
100868
- const pluginPath = resolve16(options.pluginPath ?? join57(repoRoot, "packages", "omo-senpi", "plugin"));
101570
+ const repoRoot = resolve18(options.repoRoot ?? (allowBuild ? findRepoRoot2(dirname22(fileURLToPath(import.meta.url))) : dirname22(resolve18(options.pluginPath))));
101571
+ const agentDir = resolve18(options.agentDir ?? env3.SENPI_CODING_AGENT_DIR ?? join60(homedir9(), ".senpi", "agent"));
101572
+ const pluginPath = resolve18(options.pluginPath ?? join60(repoRoot, "packages", "omo-senpi", "plugin"));
100869
101573
  return {
100870
101574
  env: env3,
100871
101575
  repoRoot,
100872
101576
  agentDir,
100873
- settingsPath: join57(agentDir, "settings.json"),
101577
+ settingsPath: join60(agentDir, "settings.json"),
100874
101578
  pluginPath,
101579
+ platform: options.platform ?? process.platform,
100875
101580
  allowBuild,
100876
101581
  runCommand: options.runCommand ?? defaultRunCommand3
100877
101582
  };
100878
101583
  }
100879
101584
  async function ensurePluginArtifacts(context) {
100880
- const missing = await hasMissingPluginArtifact(context.pluginPath);
100881
- if (!missing)
100882
- return;
100883
- if (!context.allowBuild) {
101585
+ if (context.allowBuild) {
101586
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
101587
+ await context.runCommand("node", [join60("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
101588
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
101589
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
101590
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
101591
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-ast-grep-mcp-runtime.mjs")], { cwd: context.repoRoot });
101592
+ await context.runCommand("node", [join60(context.pluginPath, "scripts", "stage-agent-toolkit.mjs")], { cwd: context.repoRoot });
101593
+ }
101594
+ if (await hasMissingPluginArtifact(context.pluginPath)) {
100884
101595
  throw new Error(`Packed omo-senpi plugin is missing required runtime artifacts at ${context.pluginPath}`);
100885
101596
  }
100886
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
100887
- await context.runCommand("node", [join57("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
100888
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
100889
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
100890
- await context.runCommand("node", [join57(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
101597
+ await verifyAstGrepRuntimeIntegrity(context.pluginPath, context.platform);
100891
101598
  }
100892
101599
  async function hasMissingPluginArtifact(pluginPath) {
100893
101600
  for (const artifact of REQUIRED_PLUGIN_ARTIFACTS) {
100894
- if (!await fileExists(join57(pluginPath, artifact)))
101601
+ if (!await fileExists2(join60(pluginPath, artifact)))
100895
101602
  return true;
100896
101603
  }
100897
101604
  return false;
100898
101605
  }
100899
- async function defaultRunCommand3(command, args, options) {
100900
- const result = await execFileAsync2(command, [...args], { cwd: options.cwd });
100901
- if (result.stderr.trim().length > 0)
100902
- process.stderr.write(result.stderr);
100903
- if (result.stdout.trim().length > 0)
100904
- process.stdout.write(result.stdout);
100905
- }
100906
- async function readSettings(settingsPath) {
100907
- let raw;
101606
+ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
101607
+ const runtimeEntry = join60(pluginPath, "runtime", "ast-grep-mcp", "cli.js");
101608
+ const manifestPath = join60(dirname22(runtimeEntry), "manifest.json");
101609
+ let runtimeStat;
100908
101610
  try {
100909
- raw = await readFile23(settingsPath, "utf8");
101611
+ runtimeStat = await stat6(runtimeEntry);
101612
+ if (!runtimeStat.isFile())
101613
+ throw new Error("runtime is not a file");
101614
+ await access2(runtimeEntry, constants8.R_OK | constants8.X_OK);
100910
101615
  } catch (error51) {
100911
- if (isErrno(error51, "ENOENT"))
100912
- return {};
100913
- throw error51;
101616
+ throw astGrepIntegrityError(runtimeEntry, `runtime is unreadable or non-executable: ${messageOf(error51)}`);
100914
101617
  }
100915
- const parsed = JSON.parse(raw);
100916
- if (!isPlainObject6(parsed))
100917
- throw new Error(`${settingsPath} must contain a JSON object`);
100918
- return parsed;
100919
- }
100920
- function readPackages(settings) {
100921
- const packages = settings.packages;
100922
- if (packages === undefined)
100923
- return [];
100924
- if (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string")) {
100925
- throw new Error("Senpi settings packages must be an array of strings");
101618
+ if (!await fileExists2(manifestPath)) {
101619
+ throw astGrepIntegrityError(runtimeEntry, `manifest is missing: ${manifestPath}`);
101620
+ }
101621
+ let manifest2;
101622
+ try {
101623
+ manifest2 = JSON.parse(await readFile26(manifestPath, "utf8"));
101624
+ } catch (error51) {
101625
+ throw astGrepIntegrityError(runtimeEntry, `manifest is unreadable or invalid JSON: ${messageOf(error51)}`);
101626
+ }
101627
+ if (!isAstGrepRuntimeManifest(manifest2)) {
101628
+ throw astGrepIntegrityError(runtimeEntry, `manifest is malformed: ${manifestPath}`);
101629
+ }
101630
+ let actualSha256;
101631
+ try {
101632
+ actualSha256 = createHash5("sha256").update(await readFile26(runtimeEntry)).digest("hex");
101633
+ } catch (error51) {
101634
+ throw astGrepIntegrityError(runtimeEntry, `runtime hash could not be computed: ${messageOf(error51)}`);
101635
+ }
101636
+ if (actualSha256 !== manifest2.sha256) {
101637
+ throw astGrepIntegrityError(runtimeEntry, `sha256 mismatch: manifest=${manifest2.sha256} actual=${actualSha256}`);
101638
+ }
101639
+ const actualMode = runtimeStat.mode & 511;
101640
+ if (platform !== "win32" && actualMode !== manifest2.mode) {
101641
+ throw astGrepIntegrityError(runtimeEntry, `mode mismatch: manifest=${manifest2.mode} actual=${actualMode}`);
100926
101642
  }
100927
- return packages;
100928
- }
100929
- function dedupePackages(packages) {
100930
- return [...new Set(packages)];
100931
101643
  }
100932
- function removeLegacyBuiltinShadows(packages, repoRoot, agentDir) {
100933
- const shadowPaths = new Set(LEGACY_BUILTIN_SHADOW_PACKAGES.map((path6) => resolve16(repoRoot, path6)));
100934
- return packages.filter((entry) => !shadowPaths.has(resolve16(agentDir, entry)));
101644
+ function isAstGrepRuntimeManifest(value) {
101645
+ if (!isRecord10(value))
101646
+ return false;
101647
+ 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));
100935
101648
  }
100936
- async function writeSettingsAtomically(settingsPath, settings) {
100937
- await mkdir9(dirname20(settingsPath), { recursive: true });
100938
- const backupPath = await nextBackupPath(settingsPath);
100939
- if (await fileExists(settingsPath)) {
100940
- await copyFile3(settingsPath, backupPath);
100941
- } else {
100942
- await writeFile13(backupPath, `{}
100943
- `, "utf8");
100944
- }
100945
- const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
100946
- await writeFile13(tempPath, `${JSON.stringify(settings, null, 2)}
100947
- `, "utf8");
100948
- await rename5(tempPath, settingsPath);
100949
- return backupPath;
101649
+ function astGrepIntegrityError(runtimeEntry, reason) {
101650
+ return new Error(`Packed omo-senpi plugin ast-grep MCP runtime integrity error at ${runtimeEntry}: ${reason}`);
100950
101651
  }
100951
- async function nextBackupPath(settingsPath) {
100952
- for (let index = 0;index < 1000; index += 1) {
100953
- const suffix = index === 0 ? "" : `-${index}`;
100954
- const candidate = `${settingsPath}.${timestampForBackup()}${suffix}.backup`;
100955
- if (!await fileExists(candidate))
100956
- return candidate;
100957
- }
100958
- throw new Error(`Unable to allocate backup path for ${settingsPath}`);
101652
+ function messageOf(error51) {
101653
+ return error51 instanceof Error ? error51.message : String(error51);
100959
101654
  }
100960
- function timestampForBackup() {
100961
- return new Date().toISOString().replace(/[-:.]/g, "");
101655
+ async function defaultRunCommand3(command, args, options) {
101656
+ const result = await execFileAsync2(command, [...args], { cwd: options.cwd });
101657
+ if (result.stderr.trim().length > 0)
101658
+ process.stderr.write(result.stderr);
101659
+ if (result.stdout.trim().length > 0)
101660
+ process.stdout.write(result.stdout);
100962
101661
  }
100963
101662
  function findRepoRoot2(importerDir) {
100964
101663
  let current = importerDir;
100965
101664
  for (let depth = 0;depth <= 7; depth += 1) {
100966
- if (fileExistsSync(join57(current, "packages", "omo-senpi", "plugin", "package.json")))
101665
+ if (fileExistsSync(join60(current, "packages", "omo-senpi", "plugin", "package.json")))
100967
101666
  return current;
100968
- current = resolve16(current, "..");
101667
+ current = resolve18(current, "..");
100969
101668
  }
100970
101669
  throw new Error("Unable to locate packages/omo-senpi/plugin/package.json from installer module");
100971
101670
  }
100972
- function isPlainObject6(value) {
100973
- return typeof value === "object" && value !== null && !Array.isArray(value);
100974
- }
100975
- async function fileExists(path6) {
101671
+ async function fileExists2(path6) {
100976
101672
  try {
100977
- await access(path6, constants7.F_OK);
101673
+ await access2(path6, constants8.F_OK);
100978
101674
  return true;
100979
101675
  } catch (error51) {
100980
- if (isErrno(error51, "ENOENT"))
101676
+ if (isErrno2(error51, "ENOENT"))
100981
101677
  return false;
100982
101678
  throw error51;
100983
101679
  }
@@ -100985,7 +101681,7 @@ async function fileExists(path6) {
100985
101681
  function fileExistsSync(path6) {
100986
101682
  return existsSync30(path6);
100987
101683
  }
100988
- function isErrno(error51, code) {
101684
+ function isErrno2(error51, code) {
100989
101685
  return error51 instanceof Error && "code" in error51 && error51.code === code;
100990
101686
  }
100991
101687
  // packages/omo-opencode/src/cli/star-request.ts
@@ -101023,19 +101719,19 @@ init_provider_availability();
101023
101719
 
101024
101720
  // packages/omo-opencode/src/cli/config-manager/add-tui-plugin-to-tui-config.ts
101025
101721
  import { existsSync as existsSync32, mkdirSync as mkdirSync10, readFileSync as readFileSync15 } from "node:fs";
101026
- import { join as join59 } from "node:path";
101722
+ import { join as join62 } from "node:path";
101027
101723
 
101028
101724
  // packages/omo-opencode/src/cli/doctor/checks/tui-plugin-config.ts
101029
101725
  init_shared();
101030
101726
  import { existsSync as existsSync31, readFileSync as readFileSync14 } from "node:fs";
101031
- import { join as join58 } from "node:path";
101727
+ import { join as join61 } from "node:path";
101032
101728
  var TUI_SUBPATH = "tui";
101033
101729
  var TUI_EXPORT_SUBPATH = `./${TUI_SUBPATH}`;
101034
101730
  function fileEntryPackageJsonPath(entry) {
101035
101731
  let path6 = entry.slice("file:".length);
101036
101732
  if (path6.startsWith("//"))
101037
101733
  path6 = path6.slice(2);
101038
- return join58(path6, "package.json");
101734
+ return join61(path6, "package.json");
101039
101735
  }
101040
101736
  function packageJsonExportsTui(pkgJsonPath) {
101041
101737
  if (!existsSync31(pkgJsonPath))
@@ -101073,7 +101769,7 @@ function packageExportsTuiForServerEntry(entry) {
101073
101769
  const packageName = packageNameFromServerEntry(entry);
101074
101770
  if (packageName === null)
101075
101771
  return null;
101076
- return packageJsonExportsTui(join58(getOpenCodeConfigDir({ binary: "opencode" }), "node_modules", packageName, "package.json"));
101772
+ return packageJsonExportsTui(join61(getOpenCodeConfigDir({ binary: "opencode" }), "node_modules", packageName, "package.json"));
101077
101773
  }
101078
101774
  function isOurFilePluginEntry(entry) {
101079
101775
  if (typeof entry !== "string" || !entry.startsWith("file:"))
@@ -101138,7 +101834,7 @@ function detectServerPluginRegistration() {
101138
101834
  }
101139
101835
  }
101140
101836
  function detectTuiPluginRegistration() {
101141
- const tuiJsonPath = join58(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
101837
+ const tuiJsonPath = join61(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
101142
101838
  if (!existsSync31(tuiJsonPath)) {
101143
101839
  return {
101144
101840
  registered: false,
@@ -101294,10 +101990,10 @@ function readConfig(path6) {
101294
101990
  return null;
101295
101991
  }
101296
101992
  function readServerConfig(configDir) {
101297
- const jsoncPath = join59(configDir, "opencode.jsonc");
101993
+ const jsoncPath = join62(configDir, "opencode.jsonc");
101298
101994
  if (existsSync32(jsoncPath))
101299
101995
  return readConfig(jsoncPath);
101300
- const jsonPath = join59(configDir, "opencode.json");
101996
+ const jsonPath = join62(configDir, "opencode.json");
101301
101997
  if (existsSync32(jsonPath))
101302
101998
  return readConfig(jsonPath);
101303
101999
  return null;
@@ -101339,7 +102035,7 @@ function ensureTuiPluginEntry(opts = {}) {
101339
102035
  if (!desiredEntry) {
101340
102036
  return { changed: false, reason: "no-server-entry" };
101341
102037
  }
101342
- const tuiJsonPath = join59(configDir, "tui.json");
102038
+ const tuiJsonPath = join62(configDir, "tui.json");
101343
102039
  const { config: config3, malformed } = readTuiConfig(tuiJsonPath);
101344
102040
  if (malformed) {
101345
102041
  return { changed: false, reason: "malformed" };
@@ -101354,13 +102050,16 @@ function ensureTuiPluginEntry(opts = {}) {
101354
102050
  }
101355
102051
 
101356
102052
  // packages/omo-opencode/src/cli/install-ast-grep-sg.ts
101357
- import { homedir as homedir9 } from "node:os";
101358
- import { join as join60 } from "node:path";
102053
+ import { homedir as homedir10 } from "node:os";
102054
+ import { join as join63 } from "node:path";
101359
102055
 
101360
102056
  // packages/shared-skills/index.mjs
102057
+ import { existsSync as existsSync33 } from "node:fs";
101361
102058
  import { fileURLToPath as fileURLToPath2 } from "node:url";
102059
+ var SKILLS_PROBE_SPECIFIERS = ["./skills/", "../skills/", "../../skills/"];
101362
102060
  function sharedSkillsRootPath() {
101363
- return fileURLToPath2(new URL("./skills/", import.meta.url));
102061
+ const candidates = SKILLS_PROBE_SPECIFIERS.map((specifier) => fileURLToPath2(new URL(specifier, import.meta.url)));
102062
+ return candidates.find((candidate2) => existsSync33(candidate2)) ?? candidates[0];
101364
102063
  }
101365
102064
 
101366
102065
  // packages/omo-opencode/src/cli/install-ast-grep-sg.ts
@@ -101374,9 +102073,9 @@ function describeResult2(result) {
101374
102073
  }
101375
102074
  async function installAstGrepForOpenCode(options = {}) {
101376
102075
  const platform = options.platform ?? process.platform;
101377
- const baseDir = join60(options.homeDir ?? homedir9(), ".omo");
102076
+ const baseDir = join63(options.homeDir ?? homedir10(), ".omo");
101378
102077
  const targetDir = astGrepRuntimeDir(baseDir, platform, options.arch ?? process.arch);
101379
- const skillDir = join60(options.sharedSkillsRoot ?? sharedSkillsRootPath(), "ast-grep");
102078
+ const skillDir = join63(options.sharedSkillsRoot ?? sharedSkillsRootPath(), "ast-grep");
101380
102079
  const installer = options.installer ?? runAstGrepSkillInstall;
101381
102080
  try {
101382
102081
  const result = await installer({ platform, skillDir, targetDir });
@@ -103324,10 +104023,10 @@ function configureCleanupCommand(program2) {
103324
104023
  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", `
103325
104024
  Examples:
103326
104025
  $ npx lazycodex-ai uninstall
103327
- $ omo uninstall --platform=codex
104026
+ $ omo-agent-toolkit uninstall --platform=codex
103328
104027
  $ npx lazycodex-ai cleanup
103329
- $ omo cleanup --platform=codex
103330
- $ omo uninstall --platform=codex --project /path/to/project
104028
+ $ omo-agent-toolkit cleanup --platform=codex
104029
+ $ omo-agent-toolkit uninstall --platform=codex --project /path/to/project
103331
104030
  `).action(async (options) => {
103332
104031
  const rootOptions = program2.opts();
103333
104032
  const platform = resolveCleanupPlatform({ platform: options.platform ?? rootOptions.platform });
@@ -104209,7 +104908,7 @@ function recordFields(value, fields) {
104209
104908
  }
104210
104909
  function modelInput(view) {
104211
104910
  const agents = isPlainRecord(view.agents) ? Object.fromEntries(Object.entries(view.agents).flatMap(([name, definition]) => {
104212
- const fields = recordFields(definition, ["description", "prompt", "model", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
104911
+ const fields = recordFields(definition, ["description", "prompt", "model", "models", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
104213
104912
  return fields === undefined ? [] : [[name, fields]];
104214
104913
  })) : undefined;
104215
104914
  const categories = isPlainRecord(view.categories) ? Object.fromEntries(Object.entries(view.categories).flatMap(([name, definition]) => {
@@ -104366,7 +105065,7 @@ function unknownPaths(schema2, value, path6) {
104366
105065
  }
104367
105066
  if (def.type === "union") {
104368
105067
  const candidates = (def.options ?? []).filter((option) => matchesShape(option, value)).map((option) => unknownPaths(option, value, path6));
104369
- return candidates.reduce((best, candidate) => best === undefined || candidate.length < best.length ? candidate : best, undefined) ?? [];
105068
+ return candidates.reduce((best, candidate2) => best === undefined || candidate2.length < best.length ? candidate2 : best, undefined) ?? [];
104370
105069
  }
104371
105070
  if (def.type === "intersection" && def.left !== undefined && def.right !== undefined) {
104372
105071
  return [...unknownPaths(def.left, value, path6), ...unknownPaths(def.right, value, path6)];
@@ -104472,6 +105171,7 @@ var AgentPermissionSchema = exports_external.object({
104472
105171
  // packages/omo-opencode/src/config/schema/agent-overrides.ts
104473
105172
  var AgentOverrideConfigSchema = exports_external.object({
104474
105173
  model: exports_external.string().optional(),
105174
+ models: exports_external.array(exports_external.union([exports_external.string(), FallbackModelObjectSchema])).optional(),
104475
105175
  fallback_models: FallbackModelsSchema.optional(),
104476
105176
  reasoning: OmoReasoningSchema.optional(),
104477
105177
  variant: exports_external.string().optional(),
@@ -105043,8 +105743,8 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
105043
105743
  });
105044
105744
  // packages/omo-opencode/src/config/validate.ts
105045
105745
  function shortPath(configPath) {
105046
- const candidate = relative7(process.cwd(), configPath);
105047
- return candidate.length > 0 ? candidate : configPath;
105746
+ const candidate2 = relative7(process.cwd(), configPath);
105747
+ return candidate2.length > 0 ? candidate2 : configPath;
105048
105748
  }
105049
105749
  function formatIssuePath(path6) {
105050
105750
  const formatted = path6.map((segment) => String(segment)).join(".");
@@ -105097,6 +105797,37 @@ function protectUserFields(config4, userConfig) {
105097
105797
  }
105098
105798
  };
105099
105799
  }
105800
+ function materializeAgentModelChains(config4) {
105801
+ if (config4.agents === undefined)
105802
+ return config4;
105803
+ let changed = false;
105804
+ const agents = Object.fromEntries(Object.entries(config4.agents).map(([name, agent2]) => {
105805
+ if (agent2?.models === undefined)
105806
+ return [name, agent2];
105807
+ const [primary, ...fallbacks] = agent2.models;
105808
+ const {
105809
+ models: _models,
105810
+ model: _model,
105811
+ fallback_models: _fallbackModels,
105812
+ reasoning: _reasoning,
105813
+ variant: _variant,
105814
+ reasoningEffort: _reasoningEffort,
105815
+ temperature: _temperature,
105816
+ top_p: _topP,
105817
+ maxTokens: _maxTokens,
105818
+ thinking: _thinking,
105819
+ ...rest
105820
+ } = agent2;
105821
+ const primarySettings = primary === undefined ? {} : typeof primary === "string" ? { model: primary } : primary;
105822
+ changed = true;
105823
+ return [name, {
105824
+ ...rest,
105825
+ ...primarySettings,
105826
+ fallback_models: fallbacks
105827
+ }];
105828
+ }));
105829
+ return changed ? { ...config4, agents } : config4;
105830
+ }
105100
105831
  function migrateRalphLoopConfig(config4) {
105101
105832
  const legacy = config4.ralph_loop;
105102
105833
  if (legacy === undefined)
@@ -105124,7 +105855,7 @@ function validatePluginConfig(directory, environment2 = process.env) {
105124
105855
  const firstFailingView = views.find((view) => view.messages.length > 0);
105125
105856
  const firstView = views[0];
105126
105857
  const userConfig = parseConfig(chain.protectedUserView);
105127
- const config4 = applyDisabledProviders(protectUserFields(mergeViews(views), userConfig));
105858
+ const config4 = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
105128
105859
  return {
105129
105860
  valid: messages.length === 0,
105130
105861
  messages,
@@ -105147,7 +105878,7 @@ var import_picocolors11 = __toESM(require_picocolors(), 1);
105147
105878
  // packages/omo-opencode/src/cli/run/opencode-binary-resolver.ts
105148
105879
  init_bun_which_shim();
105149
105880
  init_spawn_with_windows_hide();
105150
- import { delimiter as delimiter2, dirname as dirname21, posix as posix9, win32 as win325 } from "node:path";
105881
+ import { delimiter as delimiter2, dirname as dirname23, posix as posix9, win32 as win325 } from "node:path";
105151
105882
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
105152
105883
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
105153
105884
  function getCommandCandidates(platform) {
@@ -105197,15 +105928,15 @@ async function canExecuteBinary(binaryPath, spawn4 = spawnWithWindowsHide) {
105197
105928
  }
105198
105929
  async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe2 = canExecuteBinary, which2 = bunWhich, platform = process.platform) {
105199
105930
  const candidates = collectCandidateBinaryPaths(pathEnv, which2, platform);
105200
- for (const candidate of candidates) {
105201
- if (await probe2(candidate)) {
105202
- return candidate;
105931
+ for (const candidate2 of candidates) {
105932
+ if (await probe2(candidate2)) {
105933
+ return candidate2;
105203
105934
  }
105204
105935
  }
105205
105936
  return null;
105206
105937
  }
105207
105938
  function buildPathWithBinaryFirst(pathEnv, binaryPath) {
105208
- const preferredDir = dirname21(binaryPath);
105939
+ const preferredDir = dirname23(binaryPath);
105209
105940
  const existing = (pathEnv ?? "").split(delimiter2).filter((entry) => entry.length > 0 && entry !== preferredDir);
105210
105941
  return [preferredDir, ...existing].join(delimiter2);
105211
105942
  }
@@ -105374,7 +106105,7 @@ async function resolveSession(options) {
105374
106105
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
105375
106106
  const delay2 = retryDelayMs * attempt;
105376
106107
  console.log(import_picocolors12.default.dim(` Retrying in ${delay2}ms...`));
105377
- await new Promise((resolve17) => setTimeout(resolve17, delay2));
106108
+ await new Promise((resolve19) => setTimeout(resolve19, delay2));
105378
106109
  }
105379
106110
  continue;
105380
106111
  }
@@ -105385,7 +106116,7 @@ async function resolveSession(options) {
105385
106116
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
105386
106117
  const delay2 = retryDelayMs * attempt;
105387
106118
  console.log(import_picocolors12.default.dim(` Retrying in ${delay2}ms...`));
105388
- await new Promise((resolve17) => setTimeout(resolve17, delay2));
106119
+ await new Promise((resolve19) => setTimeout(resolve19, delay2));
105389
106120
  }
105390
106121
  }
105391
106122
  throw new Error("Failed to create session after all retries");
@@ -105783,9 +106514,9 @@ function isClosingFence(line, fence) {
105783
106514
  return run?.charAt(0) === fence.marker && run.length >= fence.length;
105784
106515
  }
105785
106516
  // packages/boulder-state/src/top-level-task.ts
105786
- import { existsSync as existsSync33, readFileSync as readFileSync16 } from "node:fs";
106517
+ import { existsSync as existsSync34, readFileSync as readFileSync16 } from "node:fs";
105787
106518
  function readCurrentTopLevelTask(planPath) {
105788
- if (!existsSync33(planPath)) {
106519
+ if (!existsSync34(planPath)) {
105789
106520
  return null;
105790
106521
  }
105791
106522
  try {
@@ -105796,13 +106527,13 @@ function readCurrentTopLevelTask(planPath) {
105796
106527
  }
105797
106528
  }
105798
106529
  // packages/boulder-state/src/storage/path.ts
105799
- import { existsSync as existsSync34 } from "node:fs";
105800
- import { isAbsolute as isAbsolute10, join as join61, relative as relative8, resolve as resolve17 } from "node:path";
106530
+ import { existsSync as existsSync35 } from "node:fs";
106531
+ import { isAbsolute as isAbsolute11, join as join64, relative as relative8, resolve as resolve19 } from "node:path";
105801
106532
  function getBoulderFilePath(directory) {
105802
- return join61(directory, BOULDER_DIR, BOULDER_FILE);
106533
+ return join64(directory, BOULDER_DIR, BOULDER_FILE);
105803
106534
  }
105804
106535
  function resolveTrackedPath(baseDirectory, trackedPath) {
105805
- return isAbsolute10(trackedPath) ? resolve17(trackedPath) : resolve17(baseDirectory, trackedPath);
106536
+ return isAbsolute11(trackedPath) ? resolve19(trackedPath) : resolve19(baseDirectory, trackedPath);
105806
106537
  }
105807
106538
  function resolveBoulderPlanPath(directory, state) {
105808
106539
  const absolutePlanPath = resolveTrackedPath(directory, state.active_plan);
@@ -105810,22 +106541,22 @@ function resolveBoulderPlanPath(directory, state) {
105810
106541
  if (!worktreePath) {
105811
106542
  return absolutePlanPath;
105812
106543
  }
105813
- const absoluteDirectory = resolve17(directory);
106544
+ const absoluteDirectory = resolve19(directory);
105814
106545
  const relativePlanPath = relative8(absoluteDirectory, absolutePlanPath);
105815
- if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute10(relativePlanPath)) {
106546
+ if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute11(relativePlanPath)) {
105816
106547
  return absolutePlanPath;
105817
106548
  }
105818
106549
  const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
105819
- const worktreePlanPath = resolve17(absoluteWorktreePath, relativePlanPath);
105820
- return existsSync34(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
106550
+ const worktreePlanPath = resolve19(absoluteWorktreePath, relativePlanPath);
106551
+ return existsSync35(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
105821
106552
  }
105822
106553
  function resolveBoulderPlanPathForWork(directory, work) {
105823
106554
  return resolveBoulderPlanPath(directory, work);
105824
106555
  }
105825
106556
  // packages/boulder-state/src/storage/plan-progress.ts
105826
- import { existsSync as existsSync35, readFileSync as readFileSync17, readdirSync as readdirSync7, statSync as statSync4 } from "node:fs";
106557
+ import { existsSync as existsSync36, readFileSync as readFileSync17, readdirSync as readdirSync7, statSync as statSync4 } from "node:fs";
105827
106558
  function getPlanProgress(planPath) {
105828
- if (!existsSync35(planPath)) {
106559
+ if (!existsSync36(planPath)) {
105829
106560
  return { total: 0, completed: 0, isComplete: false };
105830
106561
  }
105831
106562
  try {
@@ -105908,10 +106639,10 @@ function selectMirrorWork(state) {
105908
106639
  return sorted[0] ?? null;
105909
106640
  }
105910
106641
  // packages/boulder-state/src/storage/read-state.ts
105911
- import { existsSync as existsSync36, readFileSync as readFileSync18 } from "node:fs";
106642
+ import { existsSync as existsSync37, readFileSync as readFileSync18 } from "node:fs";
105912
106643
  function readBoulderState(directory) {
105913
106644
  const filePath = getBoulderFilePath(directory);
105914
- if (!existsSync36(filePath)) {
106645
+ if (!existsSync37(filePath)) {
105915
106646
  return null;
105916
106647
  }
105917
106648
  try {
@@ -105981,14 +106712,14 @@ init_state();
105981
106712
  // packages/omo-opencode/src/features/run-continuation-state/constants.ts
105982
106713
  var CONTINUATION_MARKER_DIR = ".omo/run-continuation";
105983
106714
  // packages/omo-opencode/src/features/run-continuation-state/storage.ts
105984
- import { existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync19, rmSync, writeFileSync as writeFileSync6 } from "node:fs";
105985
- import { join as join62 } from "node:path";
106715
+ import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync19, rmSync, writeFileSync as writeFileSync6 } from "node:fs";
106716
+ import { join as join65 } from "node:path";
105986
106717
  function getMarkerPath(directory, sessionID) {
105987
- return join62(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
106718
+ return join65(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
105988
106719
  }
105989
106720
  function readContinuationMarker(directory, sessionID) {
105990
106721
  const markerPath = getMarkerPath(directory, sessionID);
105991
- if (!existsSync37(markerPath))
106722
+ if (!existsSync38(markerPath))
105992
106723
  return null;
105993
106724
  try {
105994
106725
  const raw = readFileSync19(markerPath, "utf-8");
@@ -106057,7 +106788,7 @@ async function isSessionInBoulderLineage(input) {
106057
106788
  init_shared();
106058
106789
  init_compaction_marker();
106059
106790
  import { readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
106060
- import { join as join63 } from "node:path";
106791
+ import { join as join66 } from "node:path";
106061
106792
  var defaultSessionLastAgentDeps = {
106062
106793
  getMessageDir,
106063
106794
  isSqliteBackend,
@@ -106117,7 +106848,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
106117
106848
  try {
106118
106849
  const messages = readdirSync8(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
106119
106850
  try {
106120
- const content = readFileSync20(join63(messageDir, fileName), "utf-8");
106851
+ const content = readFileSync20(join66(messageDir, fileName), "utf-8");
106121
106852
  const parsed = JSON.parse(content);
106122
106853
  return {
106123
106854
  fileName,
@@ -106160,8 +106891,8 @@ init_agent_display_names();
106160
106891
 
106161
106892
  // packages/omo-opencode/src/hooks/ralph-loop/storage.ts
106162
106893
  init_frontmatter2();
106163
- import { existsSync as existsSync38, readFileSync as readFileSync21, writeFileSync as writeFileSync7, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12 } from "node:fs";
106164
- import { dirname as dirname22, join as join64 } from "node:path";
106894
+ import { existsSync as existsSync39, readFileSync as readFileSync21, writeFileSync as writeFileSync7, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12 } from "node:fs";
106895
+ import { dirname as dirname24, join as join67 } from "node:path";
106165
106896
 
106166
106897
  // packages/omo-opencode/src/hooks/ralph-loop/constants.ts
106167
106898
  var DEFAULT_STATE_FILE = ".omo/ralph-loop.local.md";
@@ -106170,11 +106901,11 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
106170
106901
 
106171
106902
  // packages/omo-opencode/src/hooks/ralph-loop/storage.ts
106172
106903
  function getStateFilePath(directory, customPath) {
106173
- return customPath ? join64(directory, customPath) : join64(directory, DEFAULT_STATE_FILE);
106904
+ return customPath ? join67(directory, customPath) : join67(directory, DEFAULT_STATE_FILE);
106174
106905
  }
106175
106906
  function readState(directory, customPath) {
106176
106907
  const filePath = getStateFilePath(directory, customPath);
106177
- if (!existsSync38(filePath)) {
106908
+ if (!existsSync39(filePath)) {
106178
106909
  return null;
106179
106910
  }
106180
106911
  try {
@@ -106404,7 +107135,7 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
106404
107135
  const secondaryMeaningfulWorkTimeoutMs = options.secondaryMeaningfulWorkTimeoutMs ?? DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS;
106405
107136
  const requireMeaningfulWork = options.requireMeaningfulWork ?? false;
106406
107137
  const now = options.now ?? Date.now;
106407
- const sleep = options.sleep ?? ((ms) => new Promise((resolve18) => setTimeout(resolve18, ms)));
107138
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve20) => setTimeout(resolve20, ms)));
106408
107139
  let consecutiveCompleteChecks = 0;
106409
107140
  let errorCycleCount = 0;
106410
107141
  let firstWorkTimestamp = null;
@@ -106569,7 +107300,7 @@ function createAbortError() {
106569
107300
  return error51;
106570
107301
  }
106571
107302
  function sleep(delayMs) {
106572
- return new Promise((resolve18) => setTimeout(resolve18, delayMs));
107303
+ return new Promise((resolve20) => setTimeout(resolve20, delayMs));
106573
107304
  }
106574
107305
  function hasPromptStartEvidence(eventState) {
106575
107306
  return eventState.mainSessionStarted || eventState.hasReceivedMeaningfulWork || eventState.messageCount > 0 || eventState.currentTool !== null;
@@ -106944,7 +107675,7 @@ var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
106944
107675
  async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
106945
107676
  const completed = await Promise.race([
106946
107677
  eventProcessor.then(() => true),
106947
- new Promise((resolve18) => setTimeout(() => resolve18(false), timeoutMs))
107678
+ new Promise((resolve20) => setTimeout(() => resolve20(false), timeoutMs))
106948
107679
  ]);
106949
107680
  }
106950
107681
  async function run(options) {
@@ -107270,14 +108001,14 @@ async function getLocalVersion(options = {}) {
107270
108001
  }
107271
108002
  }
107272
108003
  // packages/omo-opencode/src/cli/doctor/checks/system.ts
107273
- import { existsSync as existsSync49, readFileSync as readFileSync31 } from "node:fs";
108004
+ import { existsSync as existsSync50, readFileSync as readFileSync31 } from "node:fs";
107274
108005
 
107275
108006
  // packages/omo-opencode/src/cli/doctor/checks/system-binary.ts
107276
108007
  init_extract_semver();
107277
108008
  init_bun_which_shim();
107278
- import { existsSync as existsSync46, accessSync as accessSync4, constants as constants10 } from "node:fs";
107279
- import { homedir as homedir12 } from "node:os";
107280
- import { join as join71 } from "node:path";
108009
+ import { existsSync as existsSync47, accessSync as accessSync4, constants as constants11 } from "node:fs";
108010
+ import { homedir as homedir13 } from "node:os";
108011
+ import { join as join74 } from "node:path";
107281
108012
 
107282
108013
  // packages/omo-opencode/src/cli/doctor/framework/spawn-with-timeout.ts
107283
108014
  init_spawn_with_windows_hide();
@@ -107316,8 +108047,8 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
107316
108047
  const stdoutPromise = readSpawnStream(proc.stdout);
107317
108048
  const stderrPromise = readSpawnStream(proc.stderr);
107318
108049
  let timer;
107319
- const timeoutPromise = new Promise((resolve18) => {
107320
- timer = setTimeout(() => resolve18("timeout"), timeoutMs);
108050
+ const timeoutPromise = new Promise((resolve20) => {
108051
+ timer = setTimeout(() => resolve20("timeout"), timeoutMs);
107321
108052
  });
107322
108053
  const processPromise = (async () => {
107323
108054
  await proc.exited;
@@ -107354,7 +108085,7 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
107354
108085
  var WINDOWS_EXECUTABLE_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
107355
108086
  function isExecutable2(path12) {
107356
108087
  try {
107357
- accessSync4(path12, constants10.X_OK);
108088
+ accessSync4(path12, constants11.X_OK);
107358
108089
  return true;
107359
108090
  } catch (error51) {
107360
108091
  if (error51 instanceof Error) {
@@ -107364,22 +108095,22 @@ function isExecutable2(path12) {
107364
108095
  }
107365
108096
  }
107366
108097
  function getDesktopAppPaths(platform) {
107367
- const home = homedir12();
108098
+ const home = homedir13();
107368
108099
  switch (platform) {
107369
108100
  case "darwin":
107370
108101
  return [
107371
108102
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
107372
- join71(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
108103
+ join74(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
107373
108104
  ];
107374
108105
  case "win32": {
107375
108106
  const programFiles = process.env.ProgramFiles;
107376
108107
  const localAppData = process.env.LOCALAPPDATA;
107377
108108
  const paths2 = [];
107378
108109
  if (programFiles) {
107379
- paths2.push(join71(programFiles, "OpenCode", "OpenCode.exe"));
108110
+ paths2.push(join74(programFiles, "OpenCode", "OpenCode.exe"));
107380
108111
  }
107381
108112
  if (localAppData) {
107382
- paths2.push(join71(localAppData, "OpenCode", "OpenCode.exe"));
108113
+ paths2.push(join74(localAppData, "OpenCode", "OpenCode.exe"));
107383
108114
  }
107384
108115
  return paths2;
107385
108116
  }
@@ -107387,8 +108118,8 @@ function getDesktopAppPaths(platform) {
107387
108118
  return [
107388
108119
  "/usr/bin/opencode",
107389
108120
  "/usr/lib/opencode/opencode",
107390
- join71(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
107391
- join71(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
108121
+ join74(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
108122
+ join74(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
107392
108123
  ];
107393
108124
  default:
107394
108125
  return [];
@@ -107400,7 +108131,7 @@ function buildVersionCommand(binaryPath, platform) {
107400
108131
  }
107401
108132
  return [binaryPath, "--version"];
107402
108133
  }
107403
- function findDesktopBinary(platform = process.platform, checkExists = existsSync46) {
108134
+ function findDesktopBinary(platform = process.platform, checkExists = existsSync47) {
107404
108135
  for (const desktopPath of getDesktopAppPaths(platform)) {
107405
108136
  if (checkExists(desktopPath)) {
107406
108137
  return { binary: "opencode", path: desktopPath };
@@ -107408,7 +108139,7 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
107408
108139
  }
107409
108140
  return null;
107410
108141
  }
107411
- async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync46) {
108142
+ async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync47) {
107412
108143
  for (const binary of OPENCODE_BINARIES2) {
107413
108144
  const path12 = bunWhich(binary);
107414
108145
  if (path12 && checkExists(path12)) {
@@ -107420,7 +108151,7 @@ async function findOpenCodeBinary(platform = process.platform, checkExists = exi
107420
108151
  const candidates = getCommandCandidates2(platform);
107421
108152
  for (const entry of pathEnv.split(delimiter3).filter(Boolean)) {
107422
108153
  for (const command of candidates) {
107423
- const fullPath = join71(entry, command);
108154
+ const fullPath = join74(entry, command);
107424
108155
  if (checkExists(fullPath) && isExecutable2(fullPath)) {
107425
108156
  return { binary: command, path: fullPath };
107426
108157
  }
@@ -107466,12 +108197,12 @@ function compareVersions3(current, minimum) {
107466
108197
 
107467
108198
  // packages/omo-opencode/src/cli/doctor/checks/system-plugin.ts
107468
108199
  init_shared();
107469
- import { existsSync as existsSync47, readFileSync as readFileSync29 } from "node:fs";
108200
+ import { existsSync as existsSync48, readFileSync as readFileSync29 } from "node:fs";
107470
108201
  function detectConfigPath() {
107471
108202
  const paths2 = getOpenCodeConfigPaths({ binary: "opencode", version: null });
107472
- if (existsSync47(paths2.configJsonc))
108203
+ if (existsSync48(paths2.configJsonc))
107473
108204
  return paths2.configJsonc;
107474
- if (existsSync47(paths2.configJson))
108205
+ if (existsSync48(paths2.configJson))
107475
108206
  return paths2.configJson;
107476
108207
  return null;
107477
108208
  }
@@ -107559,36 +108290,36 @@ init_file_utils2();
107559
108290
  init_checker();
107560
108291
  init_auto_update_checker();
107561
108292
  init_package_json_locator();
107562
- import { existsSync as existsSync48, readFileSync as readFileSync30, readdirSync as readdirSync10 } from "node:fs";
108293
+ import { existsSync as existsSync49, readFileSync as readFileSync30, readdirSync as readdirSync10 } from "node:fs";
107563
108294
  import { createRequire as createRequire3 } from "node:module";
107564
- import { homedir as homedir13 } from "node:os";
107565
- import { join as join72 } from "node:path";
108295
+ import { homedir as homedir14 } from "node:os";
108296
+ import { join as join75 } from "node:path";
107566
108297
  import { fileURLToPath as fileURLToPath6 } from "node:url";
107567
108298
  init_shared();
107568
108299
  function getPlatformDefaultCacheDir(platform = process.platform) {
107569
108300
  if (platform === "darwin")
107570
- return join72(homedir13(), "Library", "Caches");
108301
+ return join75(homedir14(), "Library", "Caches");
107571
108302
  if (platform === "win32")
107572
- return process.env.LOCALAPPDATA ?? join72(homedir13(), "AppData", "Local");
107573
- return join72(homedir13(), ".cache");
108303
+ return process.env.LOCALAPPDATA ?? join75(homedir14(), "AppData", "Local");
108304
+ return join75(homedir14(), ".cache");
107574
108305
  }
107575
108306
  function resolveOpenCodeCacheDir() {
107576
108307
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
107577
108308
  if (xdgCacheHome)
107578
- return join72(xdgCacheHome, "opencode");
108309
+ return join75(xdgCacheHome, "opencode");
107579
108310
  const fromShared = getOpenCodeCacheDir();
107580
- const platformDefault = join72(getPlatformDefaultCacheDir(), "opencode");
107581
- if (existsSync48(fromShared) || !existsSync48(platformDefault))
108311
+ const platformDefault = join75(getPlatformDefaultCacheDir(), "opencode");
108312
+ if (existsSync49(fromShared) || !existsSync49(platformDefault))
107582
108313
  return fromShared;
107583
108314
  return platformDefault;
107584
108315
  }
107585
108316
  function resolveExistingDir(dirPath) {
107586
- if (!existsSync48(dirPath))
108317
+ if (!existsSync49(dirPath))
107587
108318
  return dirPath;
107588
108319
  return resolveSymlink(dirPath);
107589
108320
  }
107590
108321
  function readPackageJson(filePath) {
107591
- if (!existsSync48(filePath))
108322
+ if (!existsSync49(filePath))
107592
108323
  return null;
107593
108324
  try {
107594
108325
  const content = readFileSync30(filePath, "utf-8");
@@ -107609,34 +108340,34 @@ function normalizeVersion(value) {
107609
108340
  function createPackageCandidates(rootDir) {
107610
108341
  return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
107611
108342
  packageName,
107612
- installedPackagePath: join72(rootDir, "node_modules", packageName, "package.json")
108343
+ installedPackagePath: join75(rootDir, "node_modules", packageName, "package.json")
107613
108344
  }));
107614
108345
  }
107615
108346
  function createTaggedInstallCandidates(rootDir) {
107616
- const packagesDir = join72(rootDir, "packages");
107617
- if (!existsSync48(packagesDir))
108347
+ const packagesDir = join75(rootDir, "packages");
108348
+ if (!existsSync49(packagesDir))
107618
108349
  return [];
107619
108350
  const candidates = [];
107620
108351
  for (const entryName of readdirSync10(packagesDir).sort()) {
107621
108352
  const packageName = ACCEPTED_PACKAGE_NAMES.find((name) => entryName.startsWith(`${name}@`));
107622
108353
  if (packageName === undefined)
107623
108354
  continue;
107624
- const installDir = join72(packagesDir, entryName);
108355
+ const installDir = join75(packagesDir, entryName);
107625
108356
  candidates.push({
107626
108357
  cacheDir: installDir,
107627
- cachePackagePath: join72(installDir, "package.json"),
108358
+ cachePackagePath: join75(installDir, "package.json"),
107628
108359
  packageCandidates: [
107629
108360
  {
107630
108361
  packageName,
107631
- installedPackagePath: join72(installDir, "node_modules", packageName, "package.json")
108362
+ installedPackagePath: join75(installDir, "node_modules", packageName, "package.json")
107632
108363
  }
107633
108364
  ]
107634
108365
  });
107635
108366
  }
107636
108367
  return candidates;
107637
108368
  }
107638
- function selectInstalledPackage(candidate) {
107639
- return candidate.packageCandidates.find((packageCandidate) => existsSync48(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
108369
+ function selectInstalledPackage(candidate2) {
108370
+ return candidate2.packageCandidates.find((packageCandidate) => existsSync49(packageCandidate.installedPackagePath)) ?? candidate2.packageCandidates[0];
107640
108371
  }
107641
108372
  function getExpectedVersion(cachePackage, packageName) {
107642
108373
  return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
@@ -107647,7 +108378,7 @@ function resolveInstalledPackageJsonPath() {
107647
108378
  for (const packageName of ACCEPTED_PACKAGE_NAMES) {
107648
108379
  try {
107649
108380
  const packageJsonPath = require2.resolve(`${packageName}/package.json`);
107650
- if (existsSync48(packageJsonPath)) {
108381
+ if (existsSync49(packageJsonPath)) {
107651
108382
  return { packageName, packageJsonPath };
107652
108383
  }
107653
108384
  } catch {
@@ -107673,22 +108404,22 @@ function getLoadedPluginVersion() {
107673
108404
  const candidates = [
107674
108405
  {
107675
108406
  cacheDir: configDir,
107676
- cachePackagePath: join72(configDir, "package.json"),
108407
+ cachePackagePath: join75(configDir, "package.json"),
107677
108408
  packageCandidates: createPackageCandidates(configDir)
107678
108409
  },
107679
108410
  ...createTaggedInstallCandidates(configDir),
107680
108411
  {
107681
108412
  cacheDir,
107682
- cachePackagePath: join72(cacheDir, "package.json"),
108413
+ cachePackagePath: join75(cacheDir, "package.json"),
107683
108414
  packageCandidates: createPackageCandidates(cacheDir)
107684
108415
  },
107685
108416
  ...createTaggedInstallCandidates(cacheDir)
107686
108417
  ];
107687
- const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync48(packageCandidate.installedPackagePath))) ?? candidates[0];
108418
+ const selectedCandidate = candidates.find((candidate2) => candidate2.packageCandidates.some((packageCandidate) => existsSync49(packageCandidate.installedPackagePath))) ?? candidates[0];
107688
108419
  const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
107689
108420
  const selectedPackage = selectInstalledPackage(selectedCandidate);
107690
108421
  const candidateInstalledPath = selectedPackage.installedPackagePath;
107691
- const candidateExists = existsSync48(candidateInstalledPath);
108422
+ const candidateExists = existsSync49(candidateInstalledPath);
107692
108423
  const resolvedFallback = candidateExists ? null : resolveInstalledPackageJsonPath();
107693
108424
  const installedPackagePath = resolvedFallback?.packageJsonPath ?? candidateInstalledPath;
107694
108425
  const resolvedPackageName = resolvedFallback?.packageName ?? selectedPackage.packageName;
@@ -107724,7 +108455,7 @@ var defaultDeps6 = {
107724
108455
  getLoadedPluginVersion,
107725
108456
  getLatestPluginVersion,
107726
108457
  getSuggestedInstallTag,
107727
- configExists: existsSync49,
108458
+ configExists: existsSync50,
107728
108459
  readConfigFile: (path12) => readFileSync31(path12, "utf-8"),
107729
108460
  parseConfigContent: (content) => parseJsonc(content)
107730
108461
  };
@@ -107870,23 +108601,23 @@ async function checkSystem(deps = defaultDeps6) {
107870
108601
 
107871
108602
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-cache.ts
107872
108603
  init_shared();
107873
- import { existsSync as existsSync50, readFileSync as readFileSync32 } from "node:fs";
107874
- import { homedir as homedir14 } from "node:os";
107875
- import { join as join73 } from "node:path";
108604
+ import { existsSync as existsSync51, readFileSync as readFileSync32 } from "node:fs";
108605
+ import { homedir as homedir15 } from "node:os";
108606
+ import { join as join76 } from "node:path";
107876
108607
  function getUserConfigDir2() {
107877
108608
  const xdgConfig = process.env.XDG_CONFIG_HOME;
107878
108609
  if (xdgConfig)
107879
- return join73(xdgConfig, "opencode");
107880
- return join73(homedir14(), ".config", "opencode");
108610
+ return join76(xdgConfig, "opencode");
108611
+ return join76(homedir15(), ".config", "opencode");
107881
108612
  }
107882
108613
  function loadCustomProviderNames() {
107883
108614
  const configDir = getUserConfigDir2();
107884
108615
  const candidatePaths = [
107885
- join73(configDir, "opencode.json"),
107886
- join73(configDir, "opencode.jsonc")
108616
+ join76(configDir, "opencode.json"),
108617
+ join76(configDir, "opencode.jsonc")
107887
108618
  ];
107888
108619
  for (const configPath of candidatePaths) {
107889
- if (!existsSync50(configPath))
108620
+ if (!existsSync51(configPath))
107890
108621
  continue;
107891
108622
  try {
107892
108623
  const content = readFileSync32(configPath, "utf-8");
@@ -107904,9 +108635,9 @@ function loadCustomProviderNames() {
107904
108635
  return [];
107905
108636
  }
107906
108637
  function loadAvailableModelsFromCache() {
107907
- const cacheFile = join73(getOpenCodeCacheDir(), "models.json");
108638
+ const cacheFile = join76(getOpenCodeCacheDir(), "models.json");
107908
108639
  const customProviders = loadCustomProviderNames();
107909
- if (!existsSync50(cacheFile)) {
108640
+ if (!existsSync51(cacheFile)) {
107910
108641
  if (customProviders.length > 0) {
107911
108642
  return { providers: customProviders, modelCount: 0, cacheExists: true };
107912
108643
  }
@@ -107966,7 +108697,7 @@ function loadOmoConfig2() {
107966
108697
 
107967
108698
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-details.ts
107968
108699
  init_shared();
107969
- import { join as join74 } from "node:path";
108700
+ import { join as join77 } from "node:path";
107970
108701
 
107971
108702
  // packages/omo-opencode/src/cli/doctor/checks/model-resolution-variant.ts
107972
108703
  function formatModelWithVariant(model, variant) {
@@ -108008,7 +108739,7 @@ function formatCapabilityResolutionLabel(mode) {
108008
108739
  }
108009
108740
  function buildModelResolutionDetails(options) {
108010
108741
  const details = [];
108011
- const cacheFile = join74(getOpenCodeCacheDir(), "models.json");
108742
+ const cacheFile = join77(getOpenCodeCacheDir(), "models.json");
108012
108743
  details.push("═══ Available Models (from cache) ═══");
108013
108744
  details.push("");
108014
108745
  if (options.available.cacheExists) {
@@ -108317,24 +109048,25 @@ async function checkConfig() {
108317
109048
 
108318
109049
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
108319
109050
  init_main();
108320
- import { existsSync as existsSync51, readFileSync as readFileSync33 } from "node:fs";
108321
- import { join as join75 } from "node:path";
109051
+ import { existsSync as existsSync52, readFileSync as readFileSync33 } from "node:fs";
109052
+ import { join as join78 } from "node:path";
108322
109053
  var CANONICAL_REPLACEMENT = new Map([
108323
109054
  ["variant", "reasoning"],
108324
109055
  ["reasoningEffort", "reasoning"],
108325
- ["thinking", "reasoning"],
109056
+ ["thinking", 'reasoning: "off" or provider_options.thinking'],
108326
109057
  ["textVerbosity", "provider_options.textVerbosity"],
108327
109058
  ["fallback_models", "models"]
108328
109059
  ]);
108329
109060
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
108330
- function isRecord10(value) {
109061
+ var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
109062
+ function isRecord11(value) {
108331
109063
  return value !== null && typeof value === "object" && !Array.isArray(value);
108332
109064
  }
108333
109065
  function isHarnessBlock(key) {
108334
109066
  return key.startsWith("[") && key.endsWith("]");
108335
109067
  }
108336
109068
  function collectIssues(configPath, value, prefix) {
108337
- if (!isRecord10(value))
109069
+ if (!isRecord11(value))
108338
109070
  return [];
108339
109071
  const issues = [];
108340
109072
  for (const [key, child] of Object.entries(value)) {
@@ -108342,7 +109074,7 @@ function collectIssues(configPath, value, prefix) {
108342
109074
  const replacement = CANONICAL_REPLACEMENT.get(key);
108343
109075
  if (replacement !== undefined) {
108344
109076
  issues.push({
108345
- title: "Deprecated reasoning config key",
109077
+ title: "Deprecated config key",
108346
109078
  description: `${configPath}: ${path12}`,
108347
109079
  fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
108348
109080
  severity: "warning",
@@ -108350,7 +109082,9 @@ function collectIssues(configPath, value, prefix) {
108350
109082
  });
108351
109083
  continue;
108352
109084
  }
108353
- if (!isRecord10(child))
109085
+ if (!isRecord11(child))
109086
+ continue;
109087
+ if (PASSTHROUGH_CONTAINERS.has(key))
108354
109088
  continue;
108355
109089
  if (prefix.length === 0 && key === "profiles") {
108356
109090
  for (const profile2 of Object.values(child)) {
@@ -108358,6 +109092,8 @@ function collectIssues(configPath, value, prefix) {
108358
109092
  }
108359
109093
  continue;
108360
109094
  }
109095
+ if (key === "[opencode]")
109096
+ continue;
108361
109097
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
108362
109098
  issues.push(...collectIssues(configPath, child, path12));
108363
109099
  }
@@ -108368,13 +109104,13 @@ function userConfigPaths() {
108368
109104
  const home = process.env.HOME ?? process.env.USERPROFILE;
108369
109105
  if (home === undefined || home.length === 0)
108370
109106
  return [];
108371
- return [join75(home, ".omo", "omo.jsonc"), join75(home, ".omo", "omo.json")];
109107
+ return [join78(home, ".omo", "omo.jsonc"), join78(home, ".omo", "omo.json")];
108372
109108
  }
108373
109109
  async function checkDeprecatedReasoningKeys() {
108374
109110
  const issues = [];
108375
109111
  const scanned = [];
108376
109112
  for (const configPath of userConfigPaths()) {
108377
- if (!existsSync51(configPath))
109113
+ if (!existsSync52(configPath))
108378
109114
  continue;
108379
109115
  scanned.push(configPath);
108380
109116
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
@@ -108383,7 +109119,7 @@ async function checkDeprecatedReasoningKeys() {
108383
109119
  return {
108384
109120
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
108385
109121
  status: issues.length > 0 ? "warn" : "pass",
108386
- message: issues.length > 0 ? `${issues.length} deprecated reasoning key(s) found` : "No deprecated reasoning keys found",
109122
+ message: issues.length > 0 ? `${issues.length} deprecated config key(s) found` : "No deprecated config keys found",
108387
109123
  ...scanned.length > 0 ? { details: scanned.map((path12) => `Scanned: ${path12}`) } : {},
108388
109124
  issues
108389
109125
  };
@@ -108391,28 +109127,28 @@ async function checkDeprecatedReasoningKeys() {
108391
109127
 
108392
109128
  // packages/omo-opencode/src/cli/doctor/checks/dependencies.ts
108393
109129
  init_src2();
108394
- import { existsSync as existsSync52 } from "node:fs";
109130
+ import { existsSync as existsSync53 } from "node:fs";
108395
109131
  import { createRequire as createRequire4 } from "node:module";
108396
- import { homedir as homedir16 } from "node:os";
108397
- import { dirname as dirname27, join as join77 } from "node:path";
109132
+ import { homedir as homedir17 } from "node:os";
109133
+ import { dirname as dirname29, join as join80 } from "node:path";
108398
109134
 
108399
109135
  // packages/omo-opencode/src/hooks/comment-checker/downloader.ts
108400
- import { join as join76 } from "path";
108401
- import { homedir as homedir15, tmpdir as tmpdir4 } from "os";
109136
+ import { join as join79 } from "path";
109137
+ import { homedir as homedir16, tmpdir as tmpdir4 } from "os";
108402
109138
  init_binary_downloader();
108403
109139
  init_logger2();
108404
109140
  init_plugin_identity();
108405
109141
  var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
108406
- var DEBUG_FILE = join76(tmpdir4(), "comment-checker-debug.log");
109142
+ var DEBUG_FILE = join79(tmpdir4(), "comment-checker-debug.log");
108407
109143
  function getCacheDir2() {
108408
109144
  if (process.platform === "win32") {
108409
109145
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
108410
- const base2 = localAppData || join76(homedir15(), "AppData", "Local");
108411
- return join76(base2, CACHE_DIR_NAME, "bin");
109146
+ const base2 = localAppData || join79(homedir16(), "AppData", "Local");
109147
+ return join79(base2, CACHE_DIR_NAME, "bin");
108412
109148
  }
108413
109149
  const xdgCache = process.env.XDG_CACHE_HOME;
108414
- const base = xdgCache || join76(homedir15(), ".cache");
108415
- return join76(base, CACHE_DIR_NAME, "bin");
109150
+ const base = xdgCache || join79(homedir16(), ".cache");
109151
+ return join79(base, CACHE_DIR_NAME, "bin");
108416
109152
  }
108417
109153
  function getBinaryName() {
108418
109154
  return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
@@ -108462,7 +109198,7 @@ async function getBinaryVersion(binary) {
108462
109198
  }
108463
109199
  }
108464
109200
  async function checkAstGrepCli() {
108465
- const runtimeDir = astGrepRuntimeDir(join77(homedir16(), ".omo"));
109201
+ const runtimeDir = astGrepRuntimeDir(join80(homedir17(), ".omo"));
108466
109202
  const sgPath = findSgBinarySync({ runtimeDir });
108467
109203
  if (sgPath === null) {
108468
109204
  return {
@@ -108491,12 +109227,12 @@ function findCommentCheckerPackageBinary(baseDirOverride, resolvePackageJsonPath
108491
109227
  const binaryName = process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
108492
109228
  const platformKey = `${process.platform}-${process.arch === "x64" ? "x64" : process.arch}`;
108493
109229
  try {
108494
- const packageDir = baseDirOverride ?? dirname27(resolvePackageJsonPath());
108495
- const vendorPath = join77(packageDir, "vendor", platformKey, binaryName);
108496
- if (existsSync52(vendorPath))
109230
+ const packageDir = baseDirOverride ?? dirname29(resolvePackageJsonPath());
109231
+ const vendorPath = join80(packageDir, "vendor", platformKey, binaryName);
109232
+ if (existsSync53(vendorPath))
108497
109233
  return vendorPath;
108498
- const binPath = join77(packageDir, "bin", binaryName);
108499
- if (existsSync52(binPath))
109234
+ const binPath = join80(packageDir, "bin", binaryName);
109235
+ if (existsSync53(binPath))
108500
109236
  return binPath;
108501
109237
  } catch (error51) {
108502
109238
  if (!(error51 instanceof Error) && !isModuleResolutionFailure(error51))
@@ -108642,8 +109378,8 @@ async function getGhCliInfo(dependencies = {}) {
108642
109378
  // packages/omo-opencode/src/mcp/lsp.ts
108643
109379
  init_zod();
108644
109380
  init_opencode_config_dir();
108645
- import { existsSync as existsSync53, readFileSync as readFileSync34 } from "node:fs";
108646
- import { delimiter as delimiter3, dirname as dirname28, resolve as resolve19 } from "node:path";
109381
+ import { existsSync as existsSync54, readFileSync as readFileSync34 } from "node:fs";
109382
+ import { delimiter as delimiter3, dirname as dirname30, resolve as resolve21 } from "node:path";
108647
109383
  import { fileURLToPath as fileURLToPath7 } from "node:url";
108648
109384
 
108649
109385
  // packages/omo-opencode/src/mcp/cli-suffix.ts
@@ -108690,7 +109426,7 @@ function resolveRuntimeExecutable(commandName, options = {}) {
108690
109426
  }
108691
109427
 
108692
109428
  // packages/omo-opencode/src/mcp/shared/ancestor-cli-resolver.ts
108693
- import { resolve as resolve18 } from "node:path";
109429
+ import { resolve as resolve20 } from "node:path";
108694
109430
  function resolveJavaScriptRuntime(resolveExecutable) {
108695
109431
  const node = resolveExecutable("node");
108696
109432
  return node.available ? node : resolveExecutable("bun");
@@ -108698,9 +109434,9 @@ function resolveJavaScriptRuntime(resolveExecutable) {
108698
109434
  function createAncestorCliCandidates(options) {
108699
109435
  const candidates = [];
108700
109436
  const seenPaths = new Set;
108701
- let currentDirectory = resolve18(options.startDirectory);
109437
+ let currentDirectory = resolve20(options.startDirectory);
108702
109438
  while (true) {
108703
- const distCliPath = resolve18(currentDirectory, options.packageRel, options.distCliRel);
109439
+ const distCliPath = resolve20(currentDirectory, options.packageRel, options.distCliRel);
108704
109440
  if (!seenPaths.has(distCliPath)) {
108705
109441
  const runtime5 = resolveJavaScriptRuntime(options.resolveExecutable);
108706
109442
  seenPaths.add(distCliPath);
@@ -108712,7 +109448,7 @@ function createAncestorCliCandidates(options) {
108712
109448
  runtimeAvailable: runtime5.available
108713
109449
  });
108714
109450
  }
108715
- const sourceCliPath = resolve18(currentDirectory, options.packageRel, options.sourceCliRel);
109451
+ const sourceCliPath = resolve20(currentDirectory, options.packageRel, options.sourceCliRel);
108716
109452
  if (!seenPaths.has(sourceCliPath)) {
108717
109453
  const runtime5 = options.resolveExecutable("bun");
108718
109454
  const sourceCandidateAvailable = options.isSourceCandidateAvailable?.({
@@ -108729,7 +109465,7 @@ function createAncestorCliCandidates(options) {
108729
109465
  runtimeAvailable: runtime5.available
108730
109466
  });
108731
109467
  }
108732
- const parentDirectory = resolve18(currentDirectory, "..");
109468
+ const parentDirectory = resolve20(currentDirectory, "..");
108733
109469
  if (parentDirectory === currentDirectory)
108734
109470
  return candidates;
108735
109471
  currentDirectory = parentDirectory;
@@ -108774,7 +109510,7 @@ var LSP_BOOTSTRAP_SCRIPT = [
108774
109510
  ].join(";");
108775
109511
  function getModuleDirectory(moduleUrl) {
108776
109512
  try {
108777
- return dirname28(fileURLToPath7(moduleUrl));
109513
+ return dirname30(fileURLToPath7(moduleUrl));
108778
109514
  } catch (error51) {
108779
109515
  if (!(error51 instanceof Error))
108780
109516
  throw error51;
@@ -108782,11 +109518,11 @@ function getModuleDirectory(moduleUrl) {
108782
109518
  }
108783
109519
  }
108784
109520
  function findBootstrapRoot(candidates, pathExists) {
108785
- return candidates.find((candidate) => pathExists(resolve19(candidate.root, "package.json")))?.root ?? process.cwd();
109521
+ return candidates.find((candidate2) => pathExists(resolve21(candidate2.root, "package.json")))?.root ?? process.cwd();
108786
109522
  }
108787
109523
  function readDaemonPackageVersion(root) {
108788
109524
  try {
108789
- const packageJson = JSON.parse(readFileSync34(resolve19(root, PACKAGE_REL, "package.json"), "utf-8"));
109525
+ const packageJson = JSON.parse(readFileSync34(resolve21(root, PACKAGE_REL, "package.json"), "utf-8"));
108790
109526
  return DaemonPackageSchema.parse(packageJson).version;
108791
109527
  } catch (error51) {
108792
109528
  if (!(error51 instanceof Error))
@@ -108798,17 +109534,17 @@ function createBootstrapCandidate(root, pathExists, resolveExecutable) {
108798
109534
  const runtime5 = resolveJavaScriptRuntime(resolveExecutable);
108799
109535
  const bun = resolveExecutable("bun");
108800
109536
  const npm = resolveExecutable("npm");
108801
- const packageManifestPath = resolve19(root, PACKAGE_REL, "package.json");
109537
+ const packageManifestPath = resolve21(root, PACKAGE_REL, "package.json");
108802
109538
  return {
108803
109539
  command: [runtime5.command, "-e", LSP_BOOTSTRAP_SCRIPT, root, npm.command, bun.command],
108804
109540
  root,
108805
- path: resolve19(root, PACKAGE_REL, DIST_CLI_REL),
109541
+ path: resolve21(root, PACKAGE_REL, DIST_CLI_REL),
108806
109542
  exists: runtime5.available && npm.available && pathExists(packageManifestPath),
108807
109543
  runtimeAvailable: runtime5.available
108808
109544
  };
108809
109545
  }
108810
109546
  function resolveLspCommand(options = {}) {
108811
- const pathExists = options.exists ?? existsSync53;
109547
+ const pathExists = options.exists ?? existsSync54;
108812
109548
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
108813
109549
  const moduleDirectory = getModuleDirectory(options.moduleUrl ?? import.meta.url);
108814
109550
  const candidates = moduleDirectory ? createAncestorCliCandidates({
@@ -108818,13 +109554,13 @@ function resolveLspCommand(options = {}) {
108818
109554
  sourceCliRel: SOURCE_CLI_REL,
108819
109555
  pathExists,
108820
109556
  resolveExecutable,
108821
- isSourceCandidateAvailable: ({ root }) => pathExists(resolve19(root, LSP_TOOLS_PACKAGE_REL, DIST_CLI_REL)) && readDaemonPackageVersion(root) !== null
109557
+ isSourceCandidateAvailable: ({ root }) => pathExists(resolve21(root, LSP_TOOLS_PACKAGE_REL, DIST_CLI_REL)) && readDaemonPackageVersion(root) !== null
108822
109558
  }) : [];
108823
- const distCandidate = candidates.find((candidate) => hasCliSuffix(candidate.path, DIST_CLI_REL) && candidate.exists);
109559
+ const distCandidate = candidates.find((candidate2) => hasCliSuffix(candidate2.path, DIST_CLI_REL) && candidate2.exists);
108824
109560
  if (distCandidate) {
108825
109561
  return distCandidate;
108826
109562
  }
108827
- const sourceCandidate = candidates.find((candidate) => hasCliSuffix(candidate.path, SOURCE_CLI_REL) && candidate.exists);
109563
+ const sourceCandidate = candidates.find((candidate2) => hasCliSuffix(candidate2.path, SOURCE_CLI_REL) && candidate2.exists);
108828
109564
  if (sourceCandidate) {
108829
109565
  return sourceCandidate;
108830
109566
  }
@@ -108832,17 +109568,18 @@ function resolveLspCommand(options = {}) {
108832
109568
  }
108833
109569
  function createLspMcpConfig(options = {}) {
108834
109570
  const resolvedCommand = resolveLspCommand(options);
108835
- const cwd = resolve19(options.cwd ?? process.cwd());
109571
+ const cwd = resolve21(options.cwd ?? process.cwd());
108836
109572
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
108837
109573
  const sourceVersion = hasCliSuffix(resolvedCommand.path, SOURCE_CLI_REL) ? readDaemonPackageVersion(resolvedCommand.root) : null;
108838
109574
  return {
108839
109575
  type: "local",
108840
109576
  command: resolvedCommand.command,
108841
109577
  enabled: resolvedCommand.exists,
109578
+ cwd,
108842
109579
  environment: {
108843
- LSP_TOOLS_MCP_PROJECT_CONFIG: PROJECT_LSP_CONFIGS.map((configPath) => resolve19(cwd, configPath)).join(delimiter3),
108844
- LSP_TOOLS_MCP_USER_CONFIG: resolve19(configDir, "lsp.json"),
108845
- LSP_TOOLS_MCP_INSTALL_DECISIONS: resolve19(configDir, "lsp-install-decisions.json"),
109580
+ LSP_TOOLS_MCP_PROJECT_CONFIG: PROJECT_LSP_CONFIGS.map((configPath) => resolve21(cwd, configPath)).join(delimiter3),
109581
+ LSP_TOOLS_MCP_USER_CONFIG: resolve21(configDir, "lsp.json"),
109582
+ LSP_TOOLS_MCP_INSTALL_DECISIONS: resolve21(configDir, "lsp-install-decisions.json"),
108846
109583
  ...sourceVersion ? {
108847
109584
  [OMO_LSP_DAEMON_CLI]: resolvedCommand.path,
108848
109585
  [OMO_LSP_DAEMON_VERSION]: sourceVersion
@@ -108867,21 +109604,21 @@ function getInstalledLspServers(options = {}) {
108867
109604
 
108868
109605
  // packages/omo-opencode/src/cli/doctor/checks/tools-mcp.ts
108869
109606
  init_shared();
108870
- import { existsSync as existsSync54, readFileSync as readFileSync35 } from "node:fs";
108871
- import { homedir as homedir17 } from "node:os";
108872
- import { join as join78 } from "node:path";
109607
+ import { existsSync as existsSync55, readFileSync as readFileSync35 } from "node:fs";
109608
+ import { homedir as homedir18 } from "node:os";
109609
+ import { join as join81 } from "node:path";
108873
109610
  var BUILTIN_MCP_SERVERS = ["websearch", "context7", "grep_app", "lsp"];
108874
109611
  function getMcpConfigPaths() {
108875
109612
  return [
108876
- join78(homedir17(), ".claude", ".mcp.json"),
108877
- join78(process.cwd(), ".mcp.json"),
108878
- join78(process.cwd(), ".claude", ".mcp.json")
109613
+ join81(homedir18(), ".claude", ".mcp.json"),
109614
+ join81(process.cwd(), ".mcp.json"),
109615
+ join81(process.cwd(), ".claude", ".mcp.json")
108879
109616
  ];
108880
109617
  }
108881
109618
  function loadUserMcpConfig() {
108882
109619
  const servers = {};
108883
109620
  for (const configPath of getMcpConfigPaths()) {
108884
- if (!existsSync54(configPath))
109621
+ if (!existsSync55(configPath))
108885
109622
  continue;
108886
109623
  try {
108887
109624
  const content = readFileSync35(configPath, "utf-8");
@@ -109019,12 +109756,12 @@ async function checkTools() {
109019
109756
 
109020
109757
  // packages/omo-opencode/src/cli/doctor/checks/telemetry.ts
109021
109758
  init_src5();
109022
- import { existsSync as existsSync55, readFileSync as readFileSync36 } from "node:fs";
109759
+ import { existsSync as existsSync56, readFileSync as readFileSync36 } from "node:fs";
109023
109760
  function isTelemetryState(value) {
109024
109761
  return value !== null && typeof value === "object" && !Array.isArray(value);
109025
109762
  }
109026
109763
  function readLastActiveDay(stateFilePath) {
109027
- if (!existsSync55(stateFilePath)) {
109764
+ if (!existsSync56(stateFilePath)) {
109028
109765
  return "never";
109029
109766
  }
109030
109767
  let parsed;
@@ -109087,17 +109824,17 @@ async function probeBinary(cmd, args, spawnImpl) {
109087
109824
  }
109088
109825
 
109089
109826
  // packages/team-core/src/team-registry/paths.ts
109090
- import { homedir as homedir18 } from "node:os";
109827
+ import { homedir as homedir19 } from "node:os";
109091
109828
  import path12 from "node:path";
109092
109829
  function resolveBaseDir(config4) {
109093
- return expandHomeDirectory(config4.base_dir ?? path12.join(homedir18(), ".omo"));
109830
+ return expandHomeDirectory(config4.base_dir ?? path12.join(homedir19(), ".omo"));
109094
109831
  }
109095
109832
  function expandHomeDirectory(directoryPath3) {
109096
109833
  if (directoryPath3 === "~") {
109097
- return homedir18();
109834
+ return homedir19();
109098
109835
  }
109099
109836
  if (directoryPath3.startsWith("~/") || directoryPath3.startsWith("~\\")) {
109100
- return path12.join(homedir18(), directoryPath3.slice(2));
109837
+ return path12.join(homedir19(), directoryPath3.slice(2));
109101
109838
  }
109102
109839
  return directoryPath3;
109103
109840
  }
@@ -109154,10 +109891,10 @@ async function pathExists(dir) {
109154
109891
 
109155
109892
  // packages/omo-opencode/src/cli/doctor/checks/codex.ts
109156
109893
  init_src2();
109157
- import { existsSync as existsSync56 } from "node:fs";
109158
- import { lstat as lstat14, readdir as readdir12, readFile as readFile24 } from "node:fs/promises";
109159
- import { homedir as homedir19 } from "node:os";
109160
- import { basename as basename11, join as join79, resolve as resolve20 } from "node:path";
109894
+ import { existsSync as existsSync57 } from "node:fs";
109895
+ import { lstat as lstat15, readdir as readdir14, readFile as readFile27 } from "node:fs/promises";
109896
+ import { homedir as homedir20 } from "node:os";
109897
+ import { basename as basename11, join as join82, resolve as resolve22 } from "node:path";
109161
109898
  // packages/omo-opencode/package.json
109162
109899
  var package_default3 = {
109163
109900
  name: "@oh-my-opencode/omo-opencode",
@@ -109212,7 +109949,7 @@ var COMPANION_PLUGIN_KEY = "codex@openai-codex";
109212
109949
  var DEFAULT_PLUGIN_VERSION = "0.1.0";
109213
109950
  var COMPANION_LIFECYCLE_EVENTS = new Set(["session_start", "stop"]);
109214
109951
  var CODEX_BIN_NAMES = [
109215
- "omo",
109952
+ "omo-agent-toolkit",
109216
109953
  "omo-rules",
109217
109954
  "omo-lsp",
109218
109955
  "omo-comment-checker",
@@ -109222,13 +109959,13 @@ var CODEX_BIN_NAMES = [
109222
109959
  "omo-git-bash-hook"
109223
109960
  ];
109224
109961
  async function gatherCodexSummary(deps = {}) {
109225
- const codexHome = resolve20(deps.codexHome ?? process.env.CODEX_HOME ?? join79(homedir19(), ".codex"));
109962
+ const codexHome = resolve22(deps.codexHome ?? process.env.CODEX_HOME ?? join82(homedir20(), ".codex"));
109226
109963
  const binDir = resolveCodexInstallerBinDir({ binDir: deps.binDir, codexHome, env: process.env });
109227
109964
  const detection = await (deps.detectCodexInstallation ?? detectCodexInstallation)();
109228
109965
  const pluginRoot = await resolveInstalledPluginRoot(codexHome);
109229
- const manifest2 = pluginRoot === null ? null : await readJson(join79(pluginRoot, ".codex-plugin", "plugin.json"));
109230
- const installSnapshot = pluginRoot === null ? null : await readJson(join79(pluginRoot, "lazycodex-install.json"));
109231
- const configPath = join79(codexHome, "config.toml");
109966
+ const manifest2 = pluginRoot === null ? null : await readJson(join82(pluginRoot, ".codex-plugin", "plugin.json"));
109967
+ const installSnapshot = pluginRoot === null ? null : await readJson(join82(pluginRoot, "lazycodex-install.json"));
109968
+ const configPath = join82(codexHome, "config.toml");
109232
109969
  const pluginVersion = stringField(manifest2, "version");
109233
109970
  return {
109234
109971
  codexPath: detection.found && "path" in detection ? detection.path : null,
@@ -109285,7 +110022,7 @@ function buildCodexIssues(summary) {
109285
110022
  if (summary.pluginRoot === null) {
109286
110023
  issues.push({
109287
110024
  title: "OMO Codex plugin is not installed",
109288
- description: `Expected cached plugin at ${join79("plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2, DEFAULT_PLUGIN_VERSION)} under CODEX_HOME.`,
110025
+ description: `Expected cached plugin at ${join82("plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2, DEFAULT_PLUGIN_VERSION)} under CODEX_HOME.`,
109289
110026
  fix: "Run: npx lazycodex-ai install",
109290
110027
  severity: "error",
109291
110028
  affects: ["plugin loading"]
@@ -109299,10 +110036,10 @@ function buildCodexIssues(summary) {
109299
110036
  affects: ["version reporting"]
109300
110037
  });
109301
110038
  }
109302
- if (summary.pluginRoot !== null && !summary.linkedBins.includes("omo")) {
110039
+ if (summary.pluginRoot !== null && !summary.linkedBins.includes("omo-agent-toolkit")) {
109303
110040
  issues.push({
109304
- title: "omo runtime command is not linked",
109305
- 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.",
110041
+ title: "omo-agent-toolkit runtime command is not linked",
110042
+ 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.",
109306
110043
  fix: "Run: npx lazycodex-ai@latest install",
109307
110044
  severity: "error",
109308
110045
  affects: ["ulw-loop"]
@@ -109350,15 +110087,15 @@ function buildCodexIssues(summary) {
109350
110087
  return issues;
109351
110088
  }
109352
110089
  async function resolveInstalledPluginRoot(codexHome) {
109353
- const pluginRoot = join79(codexHome, "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2);
109354
- if (!existsSync56(pluginRoot))
110090
+ const pluginRoot = join82(codexHome, "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME2);
110091
+ if (!existsSync57(pluginRoot))
109355
110092
  return null;
109356
- const versions2 = await readdir12(pluginRoot, { withFileTypes: true });
110093
+ const versions2 = await readdir14(pluginRoot, { withFileTypes: true });
109357
110094
  const candidates = versions2.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionsDescending);
109358
- return candidates.length === 0 ? null : join79(pluginRoot, candidates[0] ?? DEFAULT_PLUGIN_VERSION);
110095
+ return candidates.length === 0 ? null : join82(pluginRoot, candidates[0] ?? DEFAULT_PLUGIN_VERSION);
109359
110096
  }
109360
110097
  async function readCodexConfigSummary(configPath) {
109361
- if (!existsSync56(configPath)) {
110098
+ if (!existsSync57(configPath)) {
109362
110099
  return {
109363
110100
  exists: false,
109364
110101
  marketplaceConfigured: false,
@@ -109369,7 +110106,7 @@ async function readCodexConfigSummary(configPath) {
109369
110106
  companionLifecycleHookStateEvents: []
109370
110107
  };
109371
110108
  }
109372
- const content = await readFile24(configPath, "utf8");
110109
+ const content = await readFile27(configPath, "utf8");
109373
110110
  return {
109374
110111
  exists: true,
109375
110112
  marketplaceConfigured: content.includes("[marketplaces.sisyphuslabs]"),
@@ -109383,21 +110120,21 @@ async function readCodexConfigSummary(configPath) {
109383
110120
  async function readLinkedBins(binDir) {
109384
110121
  const linked = [];
109385
110122
  for (const name of CODEX_BIN_NAMES) {
109386
- if (await pathExists2(join79(binDir, process.platform === "win32" ? `${name}.cmd` : name)))
110123
+ if (await pathExists2(join82(binDir, process.platform === "win32" ? `${name}.cmd` : name)))
109387
110124
  linked.push(name);
109388
110125
  }
109389
110126
  return linked;
109390
110127
  }
109391
110128
  async function readLinkedAgents(codexHome) {
109392
- const agentsDir = join79(codexHome, "agents");
109393
- if (!existsSync56(agentsDir))
110129
+ const agentsDir = join82(codexHome, "agents");
110130
+ if (!existsSync57(agentsDir))
109394
110131
  return [];
109395
- const entries = await readdir12(agentsDir, { withFileTypes: true });
110132
+ const entries = await readdir14(agentsDir, { withFileTypes: true });
109396
110133
  return entries.filter((entry) => entry.isFile() || entry.isSymbolicLink()).map((entry) => basename11(entry.name, ".toml")).sort();
109397
110134
  }
109398
110135
  async function readJson(path14) {
109399
110136
  try {
109400
- const parsed = JSON.parse(await readFile24(path14, "utf8"));
110137
+ const parsed = JSON.parse(await readFile27(path14, "utf8"));
109401
110138
  return isPlainRecord(parsed) ? parsed : null;
109402
110139
  } catch (error51) {
109403
110140
  if (error51 instanceof Error)
@@ -109492,7 +110229,7 @@ function compareVersionsDescending(left, right) {
109492
110229
  }
109493
110230
  async function pathExists2(path14) {
109494
110231
  try {
109495
- await lstat14(path14);
110232
+ await lstat15(path14);
109496
110233
  return true;
109497
110234
  } catch (error51) {
109498
110235
  if (error51 instanceof Error)
@@ -109503,9 +110240,9 @@ async function pathExists2(path14) {
109503
110240
 
109504
110241
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
109505
110242
  init_src2();
109506
- import { readdir as readdir13, readFile as readFile25, stat as stat6 } from "node:fs/promises";
109507
- import { homedir as homedir20 } from "node:os";
109508
- import { dirname as dirname29, isAbsolute as isAbsolute11, join as join80, relative as relative9, resolve as resolve21, sep as sep9 } from "node:path";
110243
+ import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "node:fs/promises";
110244
+ import { homedir as homedir21 } from "node:os";
110245
+ import { dirname as dirname31, isAbsolute as isAbsolute12, join as join83, relative as relative9, resolve as resolve23, sep as sep9 } from "node:path";
109509
110246
  var CODEX_COMPONENTS_CHECK_ID = "codex-components";
109510
110247
  var CODEX_COMPONENTS_CHECK_NAME = "codex-components";
109511
110248
  var PLUGIN_DATA_DIR_NAME = "omo-sisyphuslabs";
@@ -109515,7 +110252,7 @@ async function checkCodexComponents(deps = {}) {
109515
110252
  const env3 = deps.env ?? process.env;
109516
110253
  const platform = deps.platform ?? process.platform;
109517
110254
  const arch = deps.arch ?? process.arch;
109518
- const codexHome = resolve21(deps.codexHome ?? env3["CODEX_HOME"] ?? join80(homedir20(), ".codex"));
110255
+ const codexHome = resolve23(deps.codexHome ?? env3["CODEX_HOME"] ?? join83(homedir21(), ".codex"));
109519
110256
  const summary = await gatherCodexSummary({ ...deps, codexHome });
109520
110257
  if (summary.pluginRoot === null) {
109521
110258
  return {
@@ -109540,7 +110277,7 @@ async function checkCodexComponents(deps = {}) {
109540
110277
  });
109541
110278
  }
109542
110279
  const runtimeSgDir = runtimeSgDirectory(codexHome, platform, arch);
109543
- const runtimeSgPath = join80(runtimeSgDir, sgBinaryName(platform));
110280
+ const runtimeSgPath = join83(runtimeSgDir, sgBinaryName(platform));
109544
110281
  const sg = findSgBinarySync({
109545
110282
  arch,
109546
110283
  env: env3,
@@ -109577,12 +110314,12 @@ async function auditBundleTargets(pluginRoot) {
109577
110314
  let referencedCount = 0;
109578
110315
  for (const manifestPath of await findManifestPaths(pluginRoot, ".mcp.json")) {
109579
110316
  const manifest2 = await readJson2(manifestPath);
109580
- if (manifest2 === null || !isRecord11(manifest2["mcpServers"]))
110317
+ if (manifest2 === null || !isRecord12(manifest2["mcpServers"]))
109581
110318
  continue;
109582
- const manifestRoot = dirname29(manifestPath);
109583
- const isRootManifest = resolve21(manifestRoot) === resolve21(pluginRoot);
110319
+ const manifestRoot = dirname31(manifestPath);
110320
+ const isRootManifest = resolve23(manifestRoot) === resolve23(pluginRoot);
109584
110321
  for (const server2 of Object.values(manifest2["mcpServers"])) {
109585
- if (!isRecord11(server2) || !Array.isArray(server2["args"]))
110322
+ if (!isRecord12(server2) || !Array.isArray(server2["args"]))
109586
110323
  continue;
109587
110324
  for (const arg of server2["args"]) {
109588
110325
  if (typeof arg !== "string" || !isPluginRuntimePathArg(arg))
@@ -109600,7 +110337,7 @@ async function auditBundleTargets(pluginRoot) {
109600
110337
  continue;
109601
110338
  const commands2 = [];
109602
110339
  collectHookCommands(manifest2, commands2);
109603
- const hookPluginRoot = dirname29(dirname29(hookManifestPath));
110340
+ const hookPluginRoot = dirname31(dirname31(hookManifestPath));
109604
110341
  for (const command of commands2) {
109605
110342
  for (const relativePath of extractPluginRootPaths(command)) {
109606
110343
  referencedCount += 1;
@@ -109622,8 +110359,8 @@ function recordBrokenTarget(broken, classified, origin) {
109622
110359
  broken.push(entry);
109623
110360
  }
109624
110361
  async function classifyBundleTarget(bundleRoot, baseRoot, relativePath, allowEscape) {
109625
- const targetPath = resolve21(baseRoot, relativePath);
109626
- const bundleRootPath = resolve21(bundleRoot);
110362
+ const targetPath = resolve23(baseRoot, relativePath);
110363
+ const bundleRootPath = resolve23(bundleRoot);
109627
110364
  const bundleRootPrefix = bundleRootPath.endsWith(sep9) ? bundleRootPath : `${bundleRootPath}${sep9}`;
109628
110365
  if (targetPath !== bundleRootPath && !targetPath.startsWith(bundleRootPrefix)) {
109629
110366
  if (allowEscape)
@@ -109639,12 +110376,12 @@ async function classifyBundleTarget(bundleRoot, baseRoot, relativePath, allowEsc
109639
110376
  }
109640
110377
  async function findHookManifestPaths(root) {
109641
110378
  const paths3 = await findManifestPaths(root, "hooks.json");
109642
- return paths3.filter((path14) => dirname29(path14).endsWith(`${sep9}hooks`));
110379
+ return paths3.filter((path14) => dirname31(path14).endsWith(`${sep9}hooks`));
109643
110380
  }
109644
110381
  async function findManifestPaths(root, manifestName) {
109645
110382
  let entries;
109646
110383
  try {
109647
- entries = await readdir13(root, { withFileTypes: true });
110384
+ entries = await readdir15(root, { withFileTypes: true });
109648
110385
  } catch {
109649
110386
  return [];
109650
110387
  }
@@ -109652,7 +110389,7 @@ async function findManifestPaths(root, manifestName) {
109652
110389
  for (const entry of entries) {
109653
110390
  if (entry.name === "node_modules" || entry.name === ".git")
109654
110391
  continue;
109655
- const entryPath = join80(root, entry.name);
110392
+ const entryPath = join83(root, entry.name);
109656
110393
  if (entry.isDirectory()) {
109657
110394
  paths3.push(...await findManifestPaths(entryPath, manifestName));
109658
110395
  continue;
@@ -109668,7 +110405,7 @@ function collectHookCommands(value, commands2) {
109668
110405
  collectHookCommands(item, commands2);
109669
110406
  return;
109670
110407
  }
109671
- if (!isRecord11(value))
110408
+ if (!isRecord12(value))
109672
110409
  return;
109673
110410
  if (value["type"] === "command") {
109674
110411
  if (typeof value["command"] === "string")
@@ -109693,21 +110430,21 @@ function extractPluginRootPaths(command) {
109693
110430
  }
109694
110431
  function isPluginRuntimePathArg(arg) {
109695
110432
  const normalized = normalizePathSeparators(arg);
109696
- return normalized.endsWith(".js") && normalized.includes("/dist/") && (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("components/") || normalized.startsWith("/") || isAbsolute11(arg));
110433
+ return normalized.endsWith(".js") && normalized.includes("/dist/") && (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("components/") || normalized.startsWith("/") || isAbsolute12(arg));
109697
110434
  }
109698
110435
  function runtimeSgDirectory(codexHome, platform, arch) {
109699
- return join80(codexHome, "runtime", "ast-grep", runtimeSlug(platform, arch));
110436
+ return join83(codexHome, "runtime", "ast-grep", runtimeSlug(platform, arch));
109700
110437
  }
109701
110438
  function describeSgSource(sgPath, env3, runtimeSgDir, platform) {
109702
110439
  const override = env3[SG_PATH_ENV_KEY]?.trim();
109703
110440
  if (override !== undefined && override.length > 0 && sgPath === override)
109704
110441
  return `env override ${SG_PATH_ENV_KEY}`;
109705
- if (sgPath === join80(runtimeSgDir, sgBinaryName(platform)))
110442
+ if (sgPath === join83(runtimeSgDir, sgBinaryName(platform)))
109706
110443
  return "runtime dir";
109707
110444
  return "PATH";
109708
110445
  }
109709
110446
  async function readBootstrapStateSummary(codexHome) {
109710
- const statePath = join80(codexHome, "plugins", "data", PLUGIN_DATA_DIR_NAME, "bootstrap", "state.json");
110447
+ const statePath = join83(codexHome, "plugins", "data", PLUGIN_DATA_DIR_NAME, "bootstrap", "state.json");
109711
110448
  const raw = await readJson2(statePath);
109712
110449
  if (raw === null)
109713
110450
  return null;
@@ -109723,7 +110460,7 @@ function parseDegradedEntries(value) {
109723
110460
  return [];
109724
110461
  const entries = [];
109725
110462
  for (const item of value) {
109726
- if (!isRecord11(item))
110463
+ if (!isRecord12(item))
109727
110464
  continue;
109728
110465
  if (typeof item["component"] !== "string" || typeof item["reason"] !== "string")
109729
110466
  continue;
@@ -109756,8 +110493,8 @@ function degradedDetailLines(entries) {
109756
110493
  }
109757
110494
  async function readJson2(path14) {
109758
110495
  try {
109759
- const parsed = JSON.parse(await readFile25(path14, "utf8"));
109760
- return isRecord11(parsed) ? parsed : null;
110496
+ const parsed = JSON.parse(await readFile28(path14, "utf8"));
110497
+ return isRecord12(parsed) ? parsed : null;
109761
110498
  } catch (error51) {
109762
110499
  if (error51 instanceof Error)
109763
110500
  return null;
@@ -109766,7 +110503,7 @@ async function readJson2(path14) {
109766
110503
  }
109767
110504
  async function fileSize(path14) {
109768
110505
  try {
109769
- const stats = await stat6(path14);
110506
+ const stats = await stat7(path14);
109770
110507
  return stats.isFile() ? stats.size : undefined;
109771
110508
  } catch {
109772
110509
  return;
@@ -109778,37 +110515,47 @@ function normalizeRelative(root, target) {
109778
110515
  function normalizePathSeparators(path14) {
109779
110516
  return path14.split("\\").join("/");
109780
110517
  }
109781
- function isRecord11(value) {
110518
+ function isRecord12(value) {
109782
110519
  return typeof value === "object" && value !== null && !Array.isArray(value);
109783
110520
  }
109784
110521
 
109785
110522
  // packages/omo-opencode/src/cli/doctor/checks/codex-runtime-wrapper.ts
109786
- import { existsSync as existsSync57 } from "node:fs";
109787
- import { readFile as readFile26 } from "node:fs/promises";
109788
- import { homedir as homedir21 } from "node:os";
109789
- import { join as join81, resolve as resolve22 } from "node:path";
110523
+ import { existsSync as existsSync58 } from "node:fs";
110524
+ import { readFile as readFile29 } from "node:fs/promises";
110525
+ import { homedir as homedir22 } from "node:os";
110526
+ import { join as join84, resolve as resolve24 } from "node:path";
109790
110527
  var RUNTIME_WRAPPER_MARKER2 = "OMO_GENERATED_RUNTIME_WRAPPER";
109791
110528
  var CHECK_NAME = "codex-runtime-wrapper";
109792
110529
  var REINSTALL_COMMAND = "npx --yes lazycodex-ai@latest install --no-tui";
109793
110530
  async function checkCodexRuntimeWrapper(deps = {}) {
109794
- const codexHome = resolve22(deps.codexHome ?? process.env.CODEX_HOME ?? join81(homedir21(), ".codex"));
110531
+ const codexHome = resolve24(deps.codexHome ?? process.env.CODEX_HOME ?? join84(homedir22(), ".codex"));
109795
110532
  const binDir = resolveCodexInstallerBinDir({ binDir: deps.binDir, codexHome, env: process.env });
109796
110533
  const platform = deps.platform ?? process.platform;
109797
- const wrapperPath = join81(binDir, platform === "win32" ? "omo.cmd" : "omo");
109798
- const wrapper = await readRuntimeWrapper(wrapperPath);
110534
+ const wrapperPath = join84(binDir, platform === "win32" ? "omo-agent-toolkit.cmd" : "omo-agent-toolkit");
110535
+ const legacyWrapperPath = join84(binDir, platform === "win32" ? "omo.cmd" : "omo");
110536
+ const [wrapper, legacyWrapper] = await Promise.all([readRuntimeWrapper(wrapperPath), readRuntimeWrapper(legacyWrapperPath)]);
109799
110537
  const issues = [];
109800
110538
  if (wrapper?.includes(RUNTIME_WRAPPER_MARKER2) === true) {
109801
110539
  const targetPath = parseRuntimeTargetPath(wrapper);
109802
- if (targetPath !== null && !existsSync57(targetPath)) {
110540
+ if (targetPath !== null && !existsSync58(targetPath)) {
109803
110541
  issues.push({
109804
- title: "omo runtime wrapper target is missing",
109805
- description: `Generated omo runtime wrapper at ${wrapperPath} points to missing target ${targetPath}.`,
110542
+ title: "omo-agent-toolkit runtime wrapper target is missing",
110543
+ description: `Generated omo-agent-toolkit runtime wrapper at ${wrapperPath} points to missing target ${targetPath}.`,
109806
110544
  fix: `Run: ${REINSTALL_COMMAND}`,
109807
110545
  severity: "warning",
109808
110546
  affects: ["ulw-loop"]
109809
110547
  });
109810
110548
  }
109811
110549
  }
110550
+ if (legacyWrapper?.includes(RUNTIME_WRAPPER_MARKER2) === true) {
110551
+ issues.push({
110552
+ title: "Legacy omo runtime wrapper is still installed",
110553
+ description: `Generated legacy omo runtime wrapper remains at ${legacyWrapperPath} and may execute an outdated cached CLI.`,
110554
+ fix: `Run: ${REINSTALL_COMMAND}`,
110555
+ severity: "warning",
110556
+ affects: ["version routing"]
110557
+ });
110558
+ }
109812
110559
  return {
109813
110560
  name: CHECK_NAME,
109814
110561
  status: issues.length > 0 ? "warn" : "pass",
@@ -109819,7 +110566,7 @@ async function checkCodexRuntimeWrapper(deps = {}) {
109819
110566
  }
109820
110567
  async function readRuntimeWrapper(path14) {
109821
110568
  try {
109822
- return await readFile26(path14, "utf8");
110569
+ return await readFile29(path14, "utf8");
109823
110570
  } catch (error51) {
109824
110571
  if (error51 instanceof Error)
109825
110572
  return null;
@@ -110272,6 +111019,8 @@ init_shared();
110272
111019
  function resolveDoctorTarget(invocationName, platform) {
110273
111020
  if (platform !== undefined)
110274
111021
  return platform;
111022
+ if (process.env.OMO_EDITION === "codex")
111023
+ return "codex";
110275
111024
  return invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : "opencode";
110276
111025
  }
110277
111026
 
@@ -110300,10 +111049,10 @@ Doctor failed unexpectedly: ${message}`];
110300
111049
  }
110301
111050
 
110302
111051
  // packages/mcp-client-core/src/mcp-oauth/storage.ts
110303
- import { createHash as createHash5 } from "node:crypto";
111052
+ import { createHash as createHash6 } from "node:crypto";
110304
111053
  import {
110305
111054
  chmodSync as chmodSync4,
110306
- existsSync as existsSync60,
111055
+ existsSync as existsSync61,
110307
111056
  mkdirSync as mkdirSync14,
110308
111057
  readdirSync as readdirSync11,
110309
111058
  readFileSync as readFileSync38,
@@ -110311,15 +111060,15 @@ import {
110311
111060
  unlinkSync as unlinkSync9,
110312
111061
  writeFileSync as writeFileSync11
110313
111062
  } from "node:fs";
110314
- import { basename as basename12, dirname as dirname30, join as join84 } from "node:path";
111063
+ import { basename as basename12, dirname as dirname32, join as join87 } from "node:path";
110315
111064
 
110316
111065
  // packages/mcp-client-core/src/config-dir.ts
110317
- import { existsSync as existsSync58, realpathSync as realpathSync8 } from "node:fs";
110318
- import { homedir as homedir22 } from "node:os";
110319
- import { join as join82, resolve as resolve23 } from "node:path";
111066
+ import { existsSync as existsSync59, realpathSync as realpathSync8 } from "node:fs";
111067
+ import { homedir as homedir23 } from "node:os";
111068
+ import { join as join85, resolve as resolve25 } from "node:path";
110320
111069
  function resolveConfigPath2(pathValue) {
110321
- const resolvedPath = resolve23(pathValue);
110322
- if (!existsSync58(resolvedPath))
111070
+ const resolvedPath = resolve25(pathValue);
111071
+ if (!existsSync59(resolvedPath))
110323
111072
  return resolvedPath;
110324
111073
  try {
110325
111074
  return realpathSync8(resolvedPath);
@@ -110334,13 +111083,13 @@ function getOpenCodeCliConfigDir(env3 = process.env) {
110334
111083
  if (customConfigDir) {
110335
111084
  return resolveConfigPath2(customConfigDir);
110336
111085
  }
110337
- const xdgConfigDir = env3["XDG_CONFIG_HOME"]?.trim() || join82(homedir22(), ".config");
110338
- return resolveConfigPath2(join82(xdgConfigDir, "opencode"));
111086
+ const xdgConfigDir = env3["XDG_CONFIG_HOME"]?.trim() || join85(homedir23(), ".config");
111087
+ return resolveConfigPath2(join85(xdgConfigDir, "opencode"));
110339
111088
  }
110340
111089
 
110341
111090
  // packages/mcp-client-core/src/mcp-oauth/storage-index.ts
110342
- import { chmodSync as chmodSync3, existsSync as existsSync59, readFileSync as readFileSync37, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "node:fs";
110343
- import { join as join83 } from "node:path";
111091
+ import { chmodSync as chmodSync3, existsSync as existsSync60, readFileSync as readFileSync37, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "node:fs";
111092
+ import { join as join86 } from "node:path";
110344
111093
  var INDEX_FILE_NAME = "index.json";
110345
111094
  function isTokenIndex(value) {
110346
111095
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -110348,11 +111097,11 @@ function isTokenIndex(value) {
110348
111097
  return Object.values(value).every((entry) => typeof entry === "string");
110349
111098
  }
110350
111099
  function getIndexPath(storageDir) {
110351
- return join83(storageDir, INDEX_FILE_NAME);
111100
+ return join86(storageDir, INDEX_FILE_NAME);
110352
111101
  }
110353
111102
  function readTokenIndex(storageDir) {
110354
111103
  const indexPath = getIndexPath(storageDir);
110355
- if (!existsSync59(indexPath))
111104
+ if (!existsSync60(indexPath))
110356
111105
  return {};
110357
111106
  try {
110358
111107
  const parsed = JSON.parse(readFileSync37(indexPath, "utf-8"));
@@ -110392,16 +111141,16 @@ function deleteTokenIndexEntry(storageDir, hash2) {
110392
111141
  var STORAGE_DIR_NAME = "mcp-oauth";
110393
111142
  var LEGACY_STORAGE_FILE_NAME = "mcp-oauth.json";
110394
111143
  function getMcpOauthStorageDir() {
110395
- return join84(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
111144
+ return join87(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
110396
111145
  }
110397
111146
  function getMcpOauthServerHash(serverHost, resource) {
110398
- return createHash5("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
111147
+ return createHash6("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
110399
111148
  }
110400
111149
  function getMcpOauthStoragePath(serverHost, resource) {
110401
- return join84(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
111150
+ return join87(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
110402
111151
  }
110403
111152
  function getLegacyStoragePath() {
110404
- return join84(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
111153
+ return join87(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
110405
111154
  }
110406
111155
  function normalizeHost2(serverHost) {
110407
111156
  let host = serverHost.trim();
@@ -110462,7 +111211,7 @@ function isOAuthTokenData(value) {
110462
111211
  return clientSecret === undefined || typeof clientSecret === "string";
110463
111212
  }
110464
111213
  function readTokenFile(filePath) {
110465
- if (!existsSync60(filePath))
111214
+ if (!existsSync61(filePath))
110466
111215
  return null;
110467
111216
  try {
110468
111217
  const parsed = JSON.parse(readFileSync38(filePath, "utf-8"));
@@ -110475,7 +111224,7 @@ function readTokenFile(filePath) {
110475
111224
  }
110476
111225
  function readLegacyStore() {
110477
111226
  const filePath = getLegacyStoragePath();
110478
- if (!existsSync60(filePath))
111227
+ if (!existsSync61(filePath))
110479
111228
  return null;
110480
111229
  try {
110481
111230
  const parsed = JSON.parse(readFileSync38(filePath, "utf-8"));
@@ -110495,8 +111244,8 @@ function readLegacyStore() {
110495
111244
  }
110496
111245
  function writeTokenFile(filePath, token) {
110497
111246
  try {
110498
- const dir = dirname30(filePath);
110499
- if (!existsSync60(dir)) {
111247
+ const dir = dirname32(filePath);
111248
+ if (!existsSync61(dir)) {
110500
111249
  mkdirSync14(dir, { recursive: true });
110501
111250
  }
110502
111251
  const tempPath = `${filePath}.tmp.${Date.now()}`;
@@ -110520,7 +111269,7 @@ function saveToken(serverHost, resource, token) {
110520
111269
  }
110521
111270
  function deleteToken(serverHost, resource) {
110522
111271
  const filePath = getMcpOauthStoragePath(serverHost, resource);
110523
- if (!existsSync60(filePath))
111272
+ if (!existsSync61(filePath))
110524
111273
  return deleteLegacyToken(serverHost, resource);
110525
111274
  try {
110526
111275
  unlinkSync9(filePath);
@@ -110542,7 +111291,7 @@ function deleteLegacyToken(serverHost, resource) {
110542
111291
  if (Object.keys(store2).length === 0) {
110543
111292
  try {
110544
111293
  const filePath = getLegacyStoragePath();
110545
- if (existsSync60(filePath))
111294
+ if (existsSync61(filePath))
110546
111295
  unlinkSync9(filePath);
110547
111296
  return true;
110548
111297
  } catch (deleteError) {
@@ -110580,7 +111329,7 @@ function listTokensByHost(serverHost) {
110580
111329
  for (const [hash2, indexedKey] of Object.entries(index)) {
110581
111330
  if (!indexedKey.startsWith(prefix))
110582
111331
  continue;
110583
- const indexedToken = readTokenFile(join84(getMcpOauthStorageDir(), `${hash2}.json`));
111332
+ const indexedToken = readTokenFile(join87(getMcpOauthStorageDir(), `${hash2}.json`));
110584
111333
  if (indexedToken)
110585
111334
  result[indexedKey] = indexedToken;
110586
111335
  }
@@ -110589,13 +111338,13 @@ function listTokensByHost(serverHost) {
110589
111338
  function listAllTokens() {
110590
111339
  const result = { ...readLegacyStore() ?? {} };
110591
111340
  const dir = getMcpOauthStorageDir();
110592
- if (!existsSync60(dir))
111341
+ if (!existsSync61(dir))
110593
111342
  return result;
110594
111343
  const index = readTokenIndex(dir);
110595
111344
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
110596
111345
  if (!entry.isFile() || !entry.name.endsWith(".json") || entry.name === "index.json")
110597
111346
  continue;
110598
- const token = readTokenFile(join84(dir, entry.name));
111347
+ const token = readTokenFile(join87(dir, entry.name));
110599
111348
  const hash2 = basename12(entry.name, ".json");
110600
111349
  if (token)
110601
111350
  result[index[hash2] ?? hash2] = token;
@@ -110769,13 +111518,13 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
110769
111518
 
110770
111519
  // packages/mcp-client-core/src/mcp-oauth/oauth-authorization-flow.ts
110771
111520
  import { spawn as spawn4 } from "node:child_process";
110772
- import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
111521
+ import { createHash as createHash7, randomBytes as randomBytes2 } from "node:crypto";
110773
111522
  import { createServer as createServer2 } from "node:http";
110774
111523
  function generateCodeVerifier() {
110775
111524
  return randomBytes2(32).toString("base64url");
110776
111525
  }
110777
111526
  function generateCodeChallenge(verifier) {
110778
- return createHash6("sha256").update(verifier).digest("base64url");
111527
+ return createHash7("sha256").update(verifier).digest("base64url");
110779
111528
  }
110780
111529
  function buildAuthorizationUrl(authorizationEndpoint, options) {
110781
111530
  const url2 = new URL(authorizationEndpoint);
@@ -110795,7 +111544,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
110795
111544
  }
110796
111545
  var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
110797
111546
  function startCallbackServer(port) {
110798
- return new Promise((resolve24, reject) => {
111547
+ return new Promise((resolve26, reject) => {
110799
111548
  let timeoutId;
110800
111549
  const server2 = createServer2((request, response) => {
110801
111550
  clearTimeout(timeoutId);
@@ -110821,7 +111570,7 @@ function startCallbackServer(port) {
110821
111570
  response.writeHead(200, { "content-type": "text/html" });
110822
111571
  response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
110823
111572
  server2.close();
110824
- resolve24({ code, state: state2 });
111573
+ resolve26({ code, state: state2 });
110825
111574
  });
110826
111575
  timeoutId = setTimeout(() => {
110827
111576
  server2.close();
@@ -111161,7 +111910,7 @@ function createMcpOAuthCommand() {
111161
111910
  }
111162
111911
 
111163
111912
  // packages/omo-opencode/src/cli/boulder/boulder.ts
111164
- import { existsSync as existsSync61 } from "node:fs";
111913
+ import { existsSync as existsSync62 } from "node:fs";
111165
111914
 
111166
111915
  // packages/omo-opencode/src/cli/boulder/formatter.ts
111167
111916
  var import_picocolors22 = __toESM(require_picocolors(), 1);
@@ -111298,10 +112047,10 @@ async function boulder(options) {
111298
112047
  const boulderFilePath = getBoulderFilePath(directory);
111299
112048
  const state2 = readBoulderState(directory);
111300
112049
  if (!state2) {
111301
- const message = existsSync61(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
112050
+ const message = existsSync62(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
111302
112051
  process.stderr.write(`${message}
111303
112052
  `);
111304
- return existsSync61(boulderFilePath) ? 2 : 1;
112053
+ return existsSync62(boulderFilePath) ? 2 : 1;
111305
112054
  }
111306
112055
  const works = getBoulderWorks(state2);
111307
112056
  const filteredWorks = options.workId ? works.filter((work) => work.work_id === options.workId) : works;
@@ -111319,12 +112068,12 @@ async function boulder(options) {
111319
112068
  }
111320
112069
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
111321
112070
  import { spawn as spawn5 } from "node:child_process";
111322
- import { existsSync as existsSync62, readFileSync as readFileSync39, realpathSync as realpathSync9 } from "node:fs";
111323
- import { homedir as homedir23 } from "node:os";
112071
+ import { existsSync as existsSync63, readFileSync as readFileSync39, realpathSync as realpathSync9 } from "node:fs";
112072
+ import { homedir as homedir24 } from "node:os";
111324
112073
  var ULW_LOOP_DELEGATION_SENTINEL = "OMO_ULW_LOOP_DELEGATED";
111325
112074
  function resolveCodexUlwLoopCommand(input = {}) {
111326
112075
  const env3 = input.env ?? process.env;
111327
- const homeDir = input.homeDir ?? homedir23();
112076
+ const homeDir = input.homeDir ?? homedir24();
111328
112077
  const localComponentBin = resolveLocalUlwLoopBin(env3, homeDir);
111329
112078
  if (localComponentBin !== null)
111330
112079
  return { executable: localComponentBin, argsPrefix: [] };
@@ -111347,37 +112096,37 @@ async function codexUlwLoop(args) {
111347
112096
  console.error("Codex ulw-loop is not installed. Run: npx lazycodex-ai@latest install --no-tui");
111348
112097
  return 1;
111349
112098
  }
111350
- const { promise: promise2, resolve: resolve24 } = Promise.withResolvers();
112099
+ const { promise: promise2, resolve: resolve26 } = Promise.withResolvers();
111351
112100
  const child = spawn5(command.executable, [...command.argsPrefix, ...args], {
111352
112101
  stdio: "inherit",
111353
112102
  env: { ...process.env, [ULW_LOOP_DELEGATION_SENTINEL]: "1" }
111354
112103
  });
111355
112104
  child.on("error", (error51) => {
111356
112105
  console.error(error51.message);
111357
- resolve24(1);
112106
+ resolve26(1);
111358
112107
  });
111359
- child.on("close", (code) => resolve24(code ?? 1));
112108
+ child.on("close", (code) => resolve26(code ?? 1));
111360
112109
  return promise2;
111361
112110
  }
111362
112111
  function resolveLocalUlwLoopBin(env3, homeDir) {
111363
112112
  const candidates = resolveCodexComponentBinCandidates({ executableName: "omo-ulw-loop", env: env3, homeDir });
111364
- return candidates.find((candidate) => existsSync62(candidate)) ?? null;
112113
+ return candidates.find((candidate2) => existsSync63(candidate2)) ?? null;
111365
112114
  }
111366
112115
  function resolveLegacyLocalOmoBin(env3, homeDir, currentExecutablePaths) {
111367
112116
  const candidates = resolveCodexComponentBinCandidates({ executableName: "omo", env: env3, homeDir });
111368
- return candidates.find((candidate) => existsSync62(candidate) && !isCurrentExecutable(candidate, currentExecutablePaths) && !isGeneratedRuntimeWrapper(candidate)) ?? null;
112117
+ return candidates.find((candidate2) => existsSync63(candidate2) && !isCurrentExecutable(candidate2, currentExecutablePaths) && !isGeneratedRuntimeWrapper(candidate2)) ?? null;
111369
112118
  }
111370
- function isGeneratedRuntimeWrapper(candidate) {
112119
+ function isGeneratedRuntimeWrapper(candidate2) {
111371
112120
  try {
111372
- return readFileSync39(candidate, "utf8").includes(RUNTIME_WRAPPER_MARKER);
112121
+ return readFileSync39(candidate2, "utf8").includes(RUNTIME_WRAPPER_MARKER);
111373
112122
  } catch (error51) {
111374
112123
  if (error51 instanceof Error)
111375
112124
  return false;
111376
112125
  return false;
111377
112126
  }
111378
112127
  }
111379
- function isCurrentExecutable(candidate, currentExecutablePaths) {
111380
- const candidateRealPath = realpathOrSelf2(candidate);
112128
+ function isCurrentExecutable(candidate2, currentExecutablePaths) {
112129
+ const candidateRealPath = realpathOrSelf2(candidate2);
111381
112130
  return currentExecutablePaths.some((currentPath) => realpathOrSelf2(currentPath) === candidateRealPath);
111382
112131
  }
111383
112132
  function realpathOrSelf2(path14) {
@@ -111515,7 +112264,7 @@ init_package();
111515
112264
  var VERSION3 = package_default.version;
111516
112265
  var program2 = new Command;
111517
112266
  function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {
111518
- const defaultPlatform = invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
112267
+ const defaultPlatform = process.env.OMO_EDITION === "codex" || invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
111519
112268
  const platform = options.platform ?? defaultPlatform;
111520
112269
  if (platform === "senpi" && !isSenpiPlatformEnabled()) {
111521
112270
  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.`);
@@ -111545,7 +112294,7 @@ Examples:
111545
112294
  $ bunx oh-my-opencode install
111546
112295
  $ npx lazycodex-ai install --no-tui
111547
112296
  $ bunx oh-my-opencode install --no-tui --platform=both --claude=max20 --openai=yes --gemini=yes --copilot=no
111548
- $ omo install --platform=codex --codex-autonomous
112297
+ $ omo-agent-toolkit install --platform=codex --codex-autonomous
111549
112298
  $ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
111550
112299
 
111551
112300
  Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Bailian > MiniMax > Vercel):
@@ -111637,7 +112386,7 @@ Examples:
111637
112386
  $ bunx oh-my-opencode doctor --status # Compact dashboard
111638
112387
  $ bunx oh-my-opencode doctor --verbose # Deep diagnostics
111639
112388
  $ bunx oh-my-opencode doctor --json # JSON output
111640
- $ omo doctor --platform=codex # Codex/LazyCodex diagnostics only
112389
+ $ omo-agent-toolkit doctor --platform=codex # Codex/LazyCodex diagnostics only
111641
112390
  `).action(async (options) => {
111642
112391
  const rootOptions = program2.opts();
111643
112392
  const rootDoctorPlatform = rootOptions.platform === "opencode" || rootOptions.platform === "codex" ? rootOptions.platform : undefined;