oh-my-opencode 4.16.2 → 4.17.0

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 (234) hide show
  1. package/.agents/command/omomomo.md +1 -1
  2. package/.agents/skills/hyperplan/SKILL.md +3 -3
  3. package/.agents/skills/omomomo/SKILL.md +1 -1
  4. package/.agents/skills/pre-publish-review/SKILL.md +3 -0
  5. package/.opencode/command/omomomo.md +1 -1
  6. package/.opencode/skills/hyperplan/SKILL.md +3 -3
  7. package/.opencode/skills/pre-publish-review/SKILL.md +3 -0
  8. package/README.ja.md +4 -4
  9. package/README.ko.md +4 -4
  10. package/README.md +4 -4
  11. package/README.ru.md +4 -4
  12. package/README.zh-cn.md +4 -4
  13. package/dist/agents/hephaestus/agent.d.ts +1 -1
  14. package/dist/agents/hephaestus/gpt-5-6.d.ts +2 -0
  15. package/dist/agents/momus-gpt-5-6.d.ts +1 -0
  16. package/dist/agents/types.d.ts +2 -0
  17. package/dist/cli/index.js +947 -567
  18. package/dist/cli-node/index.js +947 -567
  19. package/dist/features/background-agent/error-classifier.d.ts +5 -0
  20. package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -1
  21. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
  22. package/dist/features/team-mode/test-support/async-test-helpers.d.ts +2 -2
  23. package/dist/index.js +523 -81
  24. package/dist/plugin/chat-message/types.d.ts +4 -0
  25. package/dist/plugin/command-execute-before.d.ts +1 -0
  26. package/dist/plugin/stop-continuation.d.ts +17 -0
  27. package/dist/shared/live-server-route.d.ts +1 -1
  28. package/dist/skills/remove-ai-slops/SKILL.md +2 -2
  29. package/dist/skills/review-work/SKILL.md +1 -1
  30. package/dist/skills/start-work/SKILL.md +5 -2
  31. package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
  32. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  33. package/dist/skills/ulw-research/SKILL.md +2 -2
  34. package/dist/skills/visual-qa/SKILL.md +1 -1
  35. package/dist/tui.js +195 -41
  36. package/package.json +15 -14
  37. package/packages/git-bash-mcp/package.json +27 -0
  38. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
  39. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +465 -248
  40. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  41. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  43. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  44. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  45. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  46. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  47. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  48. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +6 -2
  49. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +6 -2
  50. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +2 -2
  51. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +6 -2
  53. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  54. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +67 -2
  55. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  56. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +0 -13
  58. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +93 -0
  59. package/packages/omo-codex/plugin/components/rules/dist/cli.js +43 -24
  60. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  61. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  62. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +2 -1
  63. package/packages/omo-codex/plugin/components/rules/src/dynamic-target-fingerprints.ts +15 -6
  64. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +7 -2
  65. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +2 -2
  66. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +32 -0
  67. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +106 -0
  68. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  69. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  70. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +1 -79
  71. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +12 -9
  72. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  73. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  74. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +136 -76
  75. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +94 -23
  76. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +94 -14
  77. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-transport.mjs +55 -0
  78. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +72 -18
  79. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +23 -0
  80. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  81. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  82. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +23 -40
  83. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  84. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +3 -3
  85. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +7 -7
  86. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +5 -5
  87. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +26 -0
  88. package/packages/omo-codex/plugin/components/ultrawork/agents/{lazycodex-executor.toml → lazycodex-worker-low.toml} +7 -5
  89. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +26 -0
  90. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +20 -48
  91. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +17 -29
  92. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +20 -50
  93. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +22 -43
  94. package/packages/omo-codex/plugin/components/ultrawork/directive.md +55 -28
  95. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  96. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  97. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +55 -28
  98. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
  99. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  100. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +22 -0
  101. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -68
  102. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  103. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +2 -0
  104. package/packages/omo-codex/plugin/components/ulw-loop/README.md +3 -1
  105. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +55 -28
  106. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +6 -1
  107. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -2
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +405 -25
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +12 -1
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +4 -2
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +7 -0
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +16 -1
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -0
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.d.ts +6 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +20 -0
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +1 -0
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +12 -9
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +3 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +148 -0
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.d.ts +2 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +209 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +25 -2
  124. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  125. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -15
  126. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +29 -27
  127. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +6 -1
  128. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +14 -3
  129. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +10 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +12 -1
  131. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +4 -2
  132. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +27 -1
  133. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -0
  134. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +23 -0
  135. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +16 -9
  136. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +138 -0
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +208 -0
  138. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +12 -0
  139. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +4 -1
  140. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +8 -35
  141. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +24 -13
  142. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -2
  143. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +43 -8
  144. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +55 -2
  145. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +228 -0
  146. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +193 -0
  147. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +18 -0
  157. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  159. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  161. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +17 -0
  165. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -2
  167. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  170. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  171. package/packages/omo-codex/plugin/package-lock.json +13 -13
  172. package/packages/omo-codex/plugin/package.json +1 -1
  173. package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -2
  174. package/packages/omo-codex/plugin/scripts/entry-guard.mjs +26 -0
  175. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +3 -1
  176. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  177. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +39 -4
  178. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +24 -4
  179. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +3 -3
  180. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +2 -2
  181. package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +2 -2
  182. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +14 -6
  183. package/packages/omo-codex/plugin/scripts/sync-version.mjs +4 -2
  184. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +3 -3
  185. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +3 -3
  186. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +5 -5
  187. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +9 -3
  188. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +6 -3
  189. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +136 -76
  190. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +94 -23
  191. package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +94 -14
  192. package/packages/omo-codex/plugin/skills/teammode/scripts/team-transport.mjs +55 -0
  193. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +72 -18
  194. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +55 -28
  195. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -15
  196. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +29 -27
  197. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
  198. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  199. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -4
  200. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -4
  201. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +116 -10
  202. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -2
  203. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  204. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +4 -4
  205. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +4 -2
  206. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +33 -0
  207. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -4
  208. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  209. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +4 -101
  210. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +160 -23
  211. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +71 -0
  212. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +32 -0
  213. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +20 -2
  214. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -1
  215. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +4 -2
  216. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +345 -0
  217. package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +9 -40
  218. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +4 -277
  219. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  220. package/packages/omo-codex/scripts/install-config.test.mjs +22 -3
  221. package/packages/omo-codex/scripts/install-dist/install-local.mjs +508 -286
  222. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +111 -1
  223. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +2 -2
  224. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  225. package/packages/shared-skills/skills/start-work/SKILL.md +5 -2
  226. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
  227. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  228. package/packages/shared-skills/skills/ulw-research/SKILL.md +2 -2
  229. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
  230. package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
  231. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +0 -70
  232. package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +0 -98
  233. package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
  234. /package/packages/omo-codex/plugin/components/rules/bundled-rules/{hephaestus.md → hephaestus/gpt-5.5.md} +0 -0
@@ -440,7 +440,7 @@ async function readOptionalFile(path) {
440
440
  // components/bootstrap/src/worker.ts
441
441
  import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile13 } from "node:fs/promises";
442
442
  import { homedir as homedir4 } from "node:os";
443
- import { dirname as dirname8, join as join20, resolve as resolve7 } from "node:path";
443
+ import { dirname as dirname9, join as join22, resolve as resolve7 } from "node:path";
444
444
  import { fileURLToPath as fileURLToPath2 } from "node:url";
445
445
 
446
446
  // components/bootstrap/src/provision.ts
@@ -864,211 +864,185 @@ async function defaultVersionProbe2(binaryPath) {
864
864
  }
865
865
 
866
866
  // components/bootstrap/src/setup.ts
867
- import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir4, rm as rm10, stat as stat5 } from "node:fs/promises";
868
- import { join as join19 } from "node:path";
867
+ import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir5, rm as rm10, stat as stat5 } from "node:fs/promises";
868
+ import { join as join21 } from "node:path";
869
869
 
870
870
  // ../src/install/link-cached-plugin-agents.ts
871
- import { copyFile, lstat as lstat2, mkdir as mkdir4, readFile as readFile5, readdir, rm as rm6, writeFile as writeFile3 } from "node:fs/promises";
872
- import { basename as basename3, join as join9 } from "node:path";
871
+ import { copyFile, lstat as lstat3, mkdir as mkdir4, readdir as readdir2, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
872
+ import { basename as basename3, join as join10 } from "node:path";
873
873
 
874
- // ../src/install/retired-managed-agent-purge.ts
875
- import { lstat, readFile as readFile4, rm as rm5 } from "node:fs/promises";
874
+ // ../src/install/preserved-agent-settings.ts
875
+ import { lstat, readFile as readFile4, readdir, writeFile as writeFile3 } from "node:fs/promises";
876
876
  import { join as join8 } from "node:path";
877
- var RETIRED_MANAGED_AGENT_FILES = [
878
- {
879
- fileName: "codex-ultrawork-reviewer.toml",
880
- requiredMarkers: [
881
- 'name = "codex-ultrawork-reviewer"',
882
- 'description = "Strict ultrawork verification reviewer.',
883
- 'developer_instructions = """You are the ultrawork verification reviewer.'
877
+
878
+ // ../src/install/managed-agent-reasoning-defaults.ts
879
+ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
880
+ [
881
+ "explorer",
882
+ [
883
+ {
884
+ previous: { model: "gpt-5.4-mini", effort: "low" },
885
+ current: { model: "gpt-5.6-terra", effort: "medium" }
886
+ },
887
+ {
888
+ previous: { model: "gpt-5.6-terra", effort: "medium" },
889
+ current: { model: "gpt-5.6-luna", effort: "low" }
890
+ }
884
891
  ]
885
- }
886
- ];
887
- async function purgeRetiredManagedAgentFiles(input) {
888
- const agentsDir = join8(input.codexHome, "agents");
889
- if (!await exists(agentsDir))
890
- return;
891
- for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
892
- const agentPath = join8(agentsDir, retiredAgent.fileName);
893
- if (!await exists(agentPath))
894
- continue;
895
- const agentStat = await lstat(agentPath);
896
- if (agentStat.isDirectory() && !agentStat.isSymbolicLink())
897
- continue;
898
- const content = await readTextIfExists(agentPath);
899
- if (content === null || !hasRequiredMarkers(content, retiredAgent.requiredMarkers))
900
- continue;
901
- await rm5(agentPath, { force: true });
902
- }
903
- }
904
- function hasRequiredMarkers(content, markers) {
905
- return markers.every((marker) => content.includes(marker));
906
- }
907
- async function readTextIfExists(path) {
908
- try {
909
- return await readFile4(path, "utf8");
910
- } catch (error) {
911
- if (nodeErrorCode(error) === "ENOENT")
912
- return null;
913
- throw error;
914
- }
915
- }
916
- async function exists(path) {
917
- try {
918
- await lstat(path);
919
- return true;
920
- } catch (error) {
921
- if (nodeErrorCode(error) !== "ENOENT")
922
- throw error;
923
- return false;
924
- }
925
- }
926
- function nodeErrorCode(error) {
927
- if (!(error instanceof Error) || !("code" in error))
928
- return null;
929
- return typeof error.code === "string" ? error.code : null;
892
+ ],
893
+ [
894
+ "librarian",
895
+ [
896
+ {
897
+ previous: { model: "gpt-5.4-mini", effort: "low" },
898
+ current: { model: "gpt-5.6-terra", effort: "medium" }
899
+ },
900
+ {
901
+ previous: { model: "gpt-5.6-terra", effort: "medium" },
902
+ current: { model: "gpt-5.6-luna", effort: "low" }
903
+ }
904
+ ]
905
+ ],
906
+ [
907
+ "momus",
908
+ [
909
+ {
910
+ previous: { model: "gpt-5.5", effort: "xhigh" },
911
+ current: { model: "gpt-5.6-sol", effort: "ultra" }
912
+ }
913
+ ]
914
+ ],
915
+ [
916
+ "plan",
917
+ [
918
+ {
919
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
920
+ current: { model: "gpt-5.6-sol", effort: "max" }
921
+ }
922
+ ]
923
+ ],
924
+ [
925
+ "lazycodex-worker-medium",
926
+ [
927
+ {
928
+ previous: { model: "gpt-5.6-sol", effort: "high" },
929
+ current: { model: "gpt-5.6-luna", effort: "max" }
930
+ }
931
+ ]
932
+ ],
933
+ [
934
+ "lazycodex-qa-executor",
935
+ [
936
+ {
937
+ previous: { model: "gpt-5.6-terra", effort: "medium" },
938
+ current: { model: "gpt-5.6-luna", effort: "high" }
939
+ }
940
+ ]
941
+ ],
942
+ [
943
+ "lazycodex-gate-reviewer",
944
+ [
945
+ {
946
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
947
+ current: { model: "gpt-5.6-sol", effort: "high" }
948
+ }
949
+ ]
950
+ ]
951
+ ]);
952
+ function resolveManagedAgentReasoning(input) {
953
+ const steps = MANAGED_REASONING_DEFAULT_UPGRADES.get(input.agentName);
954
+ if (steps === undefined)
955
+ return input.preserved.effort;
956
+ const latest = steps[steps.length - 1];
957
+ if (latest === undefined)
958
+ return input.preserved.effort;
959
+ if (input.bundledModel !== latest.current.model || input.bundledEffort !== latest.current.effort) {
960
+ return input.preserved.effort;
961
+ }
962
+ const preservedMatchesAnyStep = steps.some((step) => input.preserved.model === step.previous.model && input.preserved.effort === step.previous.effort);
963
+ return preservedMatchesAnyStep ? latest.current.effort : input.preserved.effort;
930
964
  }
931
965
 
932
- // ../src/install/link-cached-plugin-agents.ts
933
- var MANIFEST_FILE = ".installed-agents.json";
966
+ // ../src/install/preserved-agent-settings.ts
934
967
  async function capturePreservedAgentReasoning(input) {
935
- const agentsDir = join9(input.codexHome, "agents");
936
- if (!await exists2(agentsDir))
968
+ const agentsDir = join8(input.codexHome, "agents");
969
+ if (!await exists(agentsDir))
937
970
  return new Map;
938
971
  const preserved = new Map;
939
972
  const agentEntries = await readdir(agentsDir, { withFileTypes: true });
940
973
  for (const entry of agentEntries) {
941
974
  if (!entry.name.endsWith(".toml"))
942
975
  continue;
943
- const content = await readTextIfExists2(join9(agentsDir, entry.name));
976
+ const content = await readTextIfExists(join8(agentsDir, entry.name));
944
977
  if (content === null)
945
978
  continue;
946
979
  const effort = extractReasoningEffort(content);
947
- if (effort !== null)
948
- preserved.set(agentNameFromToml(entry.name), effort);
980
+ if (effort !== null) {
981
+ preserved.set(agentNameFromToml(entry.name), {
982
+ model: extractModel(content),
983
+ effort
984
+ });
985
+ }
949
986
  }
950
987
  return preserved;
951
988
  }
952
989
  async function capturePreservedAgentServiceTier(input) {
953
- const agentsDir = join9(input.codexHome, "agents");
954
- if (!await exists2(agentsDir))
990
+ const agentsDir = join8(input.codexHome, "agents");
991
+ if (!await exists(agentsDir))
955
992
  return new Map;
956
993
  const preserved = new Map;
957
994
  const agentEntries = await readdir(agentsDir, { withFileTypes: true });
958
995
  for (const entry of agentEntries) {
959
996
  if (!entry.name.endsWith(".toml"))
960
997
  continue;
961
- const content = await readTextIfExists2(join9(agentsDir, entry.name));
998
+ const content = await readTextIfExists(join8(agentsDir, entry.name));
962
999
  if (content === null)
963
1000
  continue;
964
1001
  preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
965
1002
  }
966
1003
  return preserved;
967
1004
  }
968
- async function linkCachedPluginAgents(input) {
969
- const bundledAgents = await discoverBundledAgents(input.pluginRoot);
970
- await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
971
- if (bundledAgents.length === 0) {
972
- await writeManifest(input.pluginRoot, []);
973
- return [];
974
- }
975
- const agentsDir = join9(input.codexHome, "agents");
976
- await mkdir4(agentsDir, { recursive: true });
977
- const linked = [];
978
- for (const agentPath of bundledAgents) {
979
- const agentFileName = basename3(agentPath);
980
- const agentName = agentNameFromToml(agentFileName);
981
- const linkPath = join9(agentsDir, agentFileName);
982
- await replaceWithCopy(linkPath, agentPath);
983
- await restorePreservedReasoning({
984
- agentName,
985
- linkPath,
986
- target: agentPath,
987
- value: input.preservedReasoning?.get(agentName)
988
- });
989
- await restorePreservedServiceTier({
990
- linkPath,
991
- preserved: input.preservedServiceTier?.has(agentName) ?? false,
992
- value: input.preservedServiceTier?.get(agentName) ?? null
993
- });
994
- linked.push({ name: agentFileName, path: linkPath, target: agentPath });
995
- }
996
- await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
997
- return linked;
998
- }
999
- async function restorePreservedServiceTier(input) {
1000
- if (!input.preserved)
1005
+ async function restorePreservedReasoning(input) {
1006
+ if (input.value === undefined)
1001
1007
  return;
1002
- const content = await readFile5(input.linkPath, "utf8");
1003
- if (extractServiceTier(content) === input.value)
1008
+ const content = await readFile4(input.target, "utf8");
1009
+ const bundledEffort = extractReasoningEffort(content);
1010
+ const effort = resolveManagedAgentReasoning({
1011
+ agentName: input.agentName,
1012
+ bundledModel: extractModel(content),
1013
+ bundledEffort,
1014
+ preserved: input.value
1015
+ });
1016
+ if (bundledEffort === effort)
1004
1017
  return;
1005
- const replacement = replaceServiceTier(content, input.value);
1018
+ const replacement = replaceTopLevelStringSetting(content, "model_reasoning_effort", effort, { insertIfMissing: false });
1006
1019
  if (!replacement.replaced)
1007
1020
  return;
1008
1021
  await writeFile3(input.linkPath, replacement.content);
1009
1022
  }
1010
- async function discoverBundledAgents(pluginRoot) {
1011
- const componentsRoot = join9(pluginRoot, "components");
1012
- if (!await exists2(componentsRoot))
1013
- return [];
1014
- const componentEntries = await readdir(componentsRoot, { withFileTypes: true });
1015
- const agents = [];
1016
- for (const entry of componentEntries) {
1017
- if (!entry.isDirectory())
1018
- continue;
1019
- const agentsRoot = join9(componentsRoot, entry.name, "agents");
1020
- if (!await exists2(agentsRoot))
1021
- continue;
1022
- const agentEntries = await readdir(agentsRoot, { withFileTypes: true });
1023
- for (const file of agentEntries) {
1024
- if (!file.isFile() || !file.name.endsWith(".toml"))
1025
- continue;
1026
- agents.push(join9(agentsRoot, file.name));
1027
- }
1028
- }
1029
- agents.sort();
1030
- return agents;
1031
- }
1032
- async function replaceWithCopy(linkPath, target) {
1033
- await prepareReplacement(linkPath);
1034
- await copyFile(target, linkPath);
1035
- }
1036
- async function prepareReplacement(linkPath) {
1037
- if (!await exists2(linkPath))
1038
- return;
1039
- const entryStat = await lstat2(linkPath);
1040
- if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
1041
- throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
1042
- }
1043
- await rm6(linkPath, { force: true });
1044
- }
1045
- async function writeManifest(pluginRoot, agentPaths) {
1046
- const manifestPath = join9(pluginRoot, MANIFEST_FILE);
1047
- const payload = { agents: [...agentPaths].sort() };
1048
- await writeFile3(manifestPath, `${JSON.stringify(payload, null, "\t")}
1049
- `);
1050
- }
1051
- async function restorePreservedReasoning(input) {
1052
- if (input.value === undefined)
1023
+ async function restorePreservedServiceTier(input) {
1024
+ if (!input.preserved)
1053
1025
  return;
1054
- const content = await readFile5(input.target, "utf8");
1055
- const bundledEffort = extractReasoningEffort(content);
1056
- if (bundledEffort === input.value)
1026
+ const content = await readFile4(input.linkPath, "utf8");
1027
+ if (extractServiceTier(content) === input.value)
1057
1028
  return;
1058
- const replacement = replaceReasoningEffort(content, input.value);
1029
+ const replacement = replaceTopLevelStringSetting(content, "service_tier", input.value, { insertIfMissing: true });
1059
1030
  if (!replacement.replaced)
1060
1031
  return;
1061
1032
  await writeFile3(input.linkPath, replacement.content);
1062
1033
  }
1063
- async function readTextIfExists2(path) {
1034
+ async function readTextIfExists(path) {
1064
1035
  try {
1065
- return await readFile5(path, "utf8");
1036
+ return await readFile4(path, "utf8");
1066
1037
  } catch (error) {
1067
- if (nodeErrorCode2(error) === "ENOENT")
1038
+ if (nodeErrorCode(error) === "ENOENT")
1068
1039
  return null;
1069
1040
  throw error;
1070
1041
  }
1071
1042
  }
1043
+ function extractModel(content) {
1044
+ return extractTopLevelStringSetting(content, "model");
1045
+ }
1072
1046
  function extractReasoningEffort(content) {
1073
1047
  return extractTopLevelStringSetting(content, "model_reasoning_effort");
1074
1048
  }
@@ -1088,12 +1062,6 @@ function extractTopLevelStringSetting(content, key) {
1088
1062
  }
1089
1063
  return null;
1090
1064
  }
1091
- function replaceReasoningEffort(content, value) {
1092
- return replaceTopLevelStringSetting(content, "model_reasoning_effort", value, { insertIfMissing: false });
1093
- }
1094
- function replaceServiceTier(content, value) {
1095
- return replaceTopLevelStringSetting(content, "service_tier", value, { insertIfMissing: true });
1096
- }
1097
1065
  function replaceTopLevelStringSetting(content, key, value, options) {
1098
1066
  const lines = content.split(/\n/);
1099
1067
  for (let index = 0;index < lines.length; index += 1) {
@@ -1153,6 +1121,64 @@ function parseJsonString(value) {
1153
1121
  return null;
1154
1122
  }
1155
1123
  }
1124
+ async function exists(path) {
1125
+ try {
1126
+ await lstat(path);
1127
+ return true;
1128
+ } catch (error) {
1129
+ if (nodeErrorCode(error) !== "ENOENT")
1130
+ throw error;
1131
+ return false;
1132
+ }
1133
+ }
1134
+ function nodeErrorCode(error) {
1135
+ if (!(error instanceof Error) || !("code" in error))
1136
+ return null;
1137
+ return typeof error.code === "string" ? error.code : null;
1138
+ }
1139
+
1140
+ // ../src/install/retired-managed-agent-purge.ts
1141
+ import { lstat as lstat2, readFile as readFile5, rm as rm5 } from "node:fs/promises";
1142
+ import { join as join9 } from "node:path";
1143
+ var RETIRED_MANAGED_AGENT_FILES = [
1144
+ {
1145
+ fileName: "codex-ultrawork-reviewer.toml",
1146
+ requiredMarkers: [
1147
+ 'name = "codex-ultrawork-reviewer"',
1148
+ 'description = "Strict ultrawork verification reviewer.',
1149
+ 'developer_instructions = """You are the ultrawork verification reviewer.'
1150
+ ]
1151
+ }
1152
+ ];
1153
+ async function purgeRetiredManagedAgentFiles(input) {
1154
+ const agentsDir = join9(input.codexHome, "agents");
1155
+ if (!await exists2(agentsDir))
1156
+ return;
1157
+ for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
1158
+ const agentPath = join9(agentsDir, retiredAgent.fileName);
1159
+ if (!await exists2(agentPath))
1160
+ continue;
1161
+ const agentStat = await lstat2(agentPath);
1162
+ if (agentStat.isDirectory() && !agentStat.isSymbolicLink())
1163
+ continue;
1164
+ const content = await readTextIfExists2(agentPath);
1165
+ if (content === null || !hasRequiredMarkers(content, retiredAgent.requiredMarkers))
1166
+ continue;
1167
+ await rm5(agentPath, { force: true });
1168
+ }
1169
+ }
1170
+ function hasRequiredMarkers(content, markers) {
1171
+ return markers.every((marker) => content.includes(marker));
1172
+ }
1173
+ async function readTextIfExists2(path) {
1174
+ try {
1175
+ return await readFile5(path, "utf8");
1176
+ } catch (error) {
1177
+ if (nodeErrorCode2(error) === "ENOENT")
1178
+ return null;
1179
+ throw error;
1180
+ }
1181
+ }
1156
1182
  async function exists2(path) {
1157
1183
  try {
1158
1184
  await lstat2(path);
@@ -1169,9 +1195,102 @@ function nodeErrorCode2(error) {
1169
1195
  return typeof error.code === "string" ? error.code : null;
1170
1196
  }
1171
1197
 
1198
+ // ../src/install/link-cached-plugin-agents.ts
1199
+ var MANIFEST_FILE = ".installed-agents.json";
1200
+ async function linkCachedPluginAgents(input) {
1201
+ const bundledAgents = await discoverBundledAgents(input.pluginRoot);
1202
+ await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
1203
+ if (bundledAgents.length === 0) {
1204
+ await writeManifest(input.pluginRoot, []);
1205
+ return [];
1206
+ }
1207
+ const agentsDir = join10(input.codexHome, "agents");
1208
+ await mkdir4(agentsDir, { recursive: true });
1209
+ const linked = [];
1210
+ for (const agentPath of bundledAgents) {
1211
+ const agentFileName = basename3(agentPath);
1212
+ const agentName = agentNameFromToml2(agentFileName);
1213
+ const linkPath = join10(agentsDir, agentFileName);
1214
+ await replaceWithCopy(linkPath, agentPath);
1215
+ await restorePreservedReasoning({
1216
+ agentName,
1217
+ linkPath,
1218
+ target: agentPath,
1219
+ value: input.preservedReasoning?.get(agentName)
1220
+ });
1221
+ await restorePreservedServiceTier({
1222
+ linkPath,
1223
+ preserved: input.preservedServiceTier?.has(agentName) ?? false,
1224
+ value: input.preservedServiceTier?.get(agentName) ?? null
1225
+ });
1226
+ linked.push({ name: agentFileName, path: linkPath, target: agentPath });
1227
+ }
1228
+ await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
1229
+ return linked;
1230
+ }
1231
+ async function discoverBundledAgents(pluginRoot) {
1232
+ const componentsRoot = join10(pluginRoot, "components");
1233
+ if (!await exists3(componentsRoot))
1234
+ return [];
1235
+ const componentEntries = await readdir2(componentsRoot, { withFileTypes: true });
1236
+ const agents = [];
1237
+ for (const entry of componentEntries) {
1238
+ if (!entry.isDirectory())
1239
+ continue;
1240
+ const agentsRoot = join10(componentsRoot, entry.name, "agents");
1241
+ if (!await exists3(agentsRoot))
1242
+ continue;
1243
+ const agentEntries = await readdir2(agentsRoot, { withFileTypes: true });
1244
+ for (const file of agentEntries) {
1245
+ if (!file.isFile() || !file.name.endsWith(".toml"))
1246
+ continue;
1247
+ agents.push(join10(agentsRoot, file.name));
1248
+ }
1249
+ }
1250
+ agents.sort();
1251
+ return agents;
1252
+ }
1253
+ async function replaceWithCopy(linkPath, target) {
1254
+ await prepareReplacement(linkPath);
1255
+ await copyFile(target, linkPath);
1256
+ }
1257
+ async function prepareReplacement(linkPath) {
1258
+ if (!await exists3(linkPath))
1259
+ return;
1260
+ const entryStat = await lstat3(linkPath);
1261
+ if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
1262
+ throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
1263
+ }
1264
+ await rm6(linkPath, { force: true });
1265
+ }
1266
+ async function writeManifest(pluginRoot, agentPaths) {
1267
+ const manifestPath = join10(pluginRoot, MANIFEST_FILE);
1268
+ const payload = { agents: [...agentPaths].sort() };
1269
+ await writeFile4(manifestPath, `${JSON.stringify(payload, null, "\t")}
1270
+ `);
1271
+ }
1272
+ function agentNameFromToml2(fileName) {
1273
+ return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
1274
+ }
1275
+ async function exists3(path) {
1276
+ try {
1277
+ await lstat3(path);
1278
+ return true;
1279
+ } catch (error) {
1280
+ if (nodeErrorCode3(error) !== "ENOENT")
1281
+ throw error;
1282
+ return false;
1283
+ }
1284
+ }
1285
+ function nodeErrorCode3(error) {
1286
+ if (!(error instanceof Error) || !("code" in error))
1287
+ return null;
1288
+ return typeof error.code === "string" ? error.code : null;
1289
+ }
1290
+
1172
1291
  // ../src/install/codex-cache-bins.ts
1173
- import { chmod as chmod2, lstat as lstat6, mkdir as mkdir5, readFile as readFile8, readdir as readdir3, readlink as readlink3, rm as rm9, stat as stat4, symlink, writeFile as writeFile4 } from "node:fs/promises";
1174
- import { basename as basename4, isAbsolute as isAbsolute3, join as join13, relative as relative2, resolve as resolve4, sep } from "node:path";
1292
+ import { chmod as chmod2, lstat as lstat7, mkdir as mkdir5, readFile as readFile8, readdir as readdir4, readlink as readlink3, rm as rm9, stat as stat4, symlink, writeFile as writeFile5 } from "node:fs/promises";
1293
+ import { basename as basename4, isAbsolute as isAbsolute3, join as join14, relative as relative2, resolve as resolve4, sep } from "node:path";
1175
1294
 
1176
1295
  // ../src/install/codex-cache-command-shim.ts
1177
1296
  var COMMAND_SHIM_MARKER = ":: generated by oh-my-openagent Codex installer";
@@ -1215,14 +1334,14 @@ function windowsCommandShim(targetPath) {
1215
1334
  }
1216
1335
 
1217
1336
  // ../src/install/codex-cache-dangling-bins.ts
1218
- import { lstat as lstat4, readFile as readFile6, readdir as readdir2, readlink, rm as rm7, stat as stat3 } from "node:fs/promises";
1219
- import { dirname as dirname5, isAbsolute as isAbsolute2, join as join10, resolve as resolve3 } from "node:path";
1337
+ import { lstat as lstat5, readFile as readFile6, readdir as readdir3, readlink, rm as rm7, stat as stat3 } from "node:fs/promises";
1338
+ import { dirname as dirname5, isAbsolute as isAbsolute2, join as join11, resolve as resolve3 } from "node:path";
1220
1339
 
1221
1340
  // ../src/install/codex-cache-fs.ts
1222
- import { lstat as lstat3 } from "node:fs/promises";
1341
+ import { lstat as lstat4 } from "node:fs/promises";
1223
1342
  async function fileExistsStrict(path) {
1224
1343
  try {
1225
- await lstat3(path);
1344
+ await lstat4(path);
1226
1345
  return true;
1227
1346
  } catch (error) {
1228
1347
  if (isNodeErrorWithCode(error) && error.code === "ENOENT")
@@ -1239,12 +1358,12 @@ function isNodeErrorWithCode(error) {
1239
1358
 
1240
1359
  // ../src/install/codex-cache-dangling-bins.ts
1241
1360
  async function removeDanglingManagedComponentBins(binDir, platform, managedBinNames) {
1242
- const entries = await readdir2(binDir, { withFileTypes: true });
1361
+ const entries = await readdir3(binDir, { withFileTypes: true });
1243
1362
  for (const entry of entries) {
1244
1363
  const binName = managedBinNameForEntry(entry.name, platform);
1245
1364
  if (binName === null || !managedBinNames.has(binName))
1246
1365
  continue;
1247
- const linkPath = join10(binDir, entry.name);
1366
+ const linkPath = join11(binDir, entry.name);
1248
1367
  if (platform === "win32") {
1249
1368
  await removeDanglingGeneratedCommandShim(linkPath);
1250
1369
  continue;
@@ -1259,7 +1378,7 @@ function managedBinNameForEntry(name, platform) {
1259
1378
  }
1260
1379
  async function removeDanglingManagedSymlink(linkPath) {
1261
1380
  try {
1262
- const linkStat = await lstat4(linkPath);
1381
+ const linkStat = await lstat5(linkPath);
1263
1382
  if (!linkStat.isSymbolicLink())
1264
1383
  return;
1265
1384
  const linkTarget = await readlink(linkPath);
@@ -1274,7 +1393,7 @@ async function removeDanglingManagedSymlink(linkPath) {
1274
1393
  }
1275
1394
  async function removeDanglingGeneratedCommandShim(linkPath) {
1276
1395
  try {
1277
- const linkStat = await lstat4(linkPath);
1396
+ const linkStat = await lstat5(linkPath);
1278
1397
  if (!linkStat.isFile())
1279
1398
  return;
1280
1399
  const content = await readFile6(linkPath, "utf8");
@@ -1325,8 +1444,8 @@ function hasOmoCodexPluginPrefix(parts, endExclusive) {
1325
1444
  }
1326
1445
 
1327
1446
  // ../src/install/codex-cache-legacy-bins.ts
1328
- import { lstat as lstat5, readFile as readFile7, readlink as readlink2, rm as rm8 } from "node:fs/promises";
1329
- import { join as join11 } from "node:path";
1447
+ import { lstat as lstat6, readFile as readFile7, readlink as readlink2, rm as rm8 } from "node:fs/promises";
1448
+ import { join as join12 } from "node:path";
1330
1449
  var LEGACY_CODEX_COMPONENT_BINS = [
1331
1450
  { name: "omo", component: "ulw-loop" },
1332
1451
  { name: "codex-comment-checker", component: "comment-checker" },
@@ -1338,13 +1457,13 @@ var LEGACY_CODEX_COMPONENT_BINS = [
1338
1457
  ];
1339
1458
  async function removeLegacyCodexComponentBins(binDir, platform) {
1340
1459
  for (const entry of LEGACY_CODEX_COMPONENT_BINS) {
1341
- const linkPath = join11(binDir, platform === "win32" ? `${entry.name}.cmd` : entry.name);
1460
+ const linkPath = join12(binDir, platform === "win32" ? `${entry.name}.cmd` : entry.name);
1342
1461
  await removeLegacyCodexComponentBin(linkPath, entry.component, platform);
1343
1462
  }
1344
1463
  }
1345
1464
  async function removeLegacyCodexComponentBin(linkPath, component, platform) {
1346
1465
  try {
1347
- const stat4 = await lstat5(linkPath);
1466
+ const stat4 = await lstat6(linkPath);
1348
1467
  if (platform !== "win32") {
1349
1468
  if (!stat4.isSymbolicLink())
1350
1469
  return;
@@ -1389,10 +1508,10 @@ function isNodeErrorWithCode2(error) {
1389
1508
  }
1390
1509
 
1391
1510
  // ../src/install/codex-cache-runtime-wrapper.ts
1392
- import { join as join12 } from "node:path";
1511
+ import { join as join13 } from "node:path";
1393
1512
  var RUNTIME_WRAPPER_MARKER = "OMO_GENERATED_RUNTIME_WRAPPER";
1394
1513
  function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
1395
- const ulwLoopBin = toPosixPath(join12(binDir, "omo-ulw-loop"));
1514
+ const ulwLoopBin = toPosixPath(join13(binDir, "omo-ulw-loop"));
1396
1515
  const nodeCli = escapePosixDoubleQuoted(toPosixPath(nodeCliPath));
1397
1516
  const escapedCliPath = escapePosixDoubleQuoted(toPosixPath(cliPath));
1398
1517
  const escapedCodexHome = escapePosixDoubleQuoted(toPosixPath(codexHome));
@@ -1437,7 +1556,7 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
1437
1556
  `);
1438
1557
  }
1439
1558
  function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
1440
- const ulwLoopBin = join12(binDir, "omo-ulw-loop.cmd");
1559
+ const ulwLoopBin = join13(binDir, "omo-ulw-loop.cmd");
1441
1560
  return [
1442
1561
  "@echo off",
1443
1562
  `rem ${RUNTIME_WRAPPER_MARKER}`,
@@ -1494,29 +1613,29 @@ async function linkCachedPluginBins(input) {
1494
1613
  return linked;
1495
1614
  }
1496
1615
  async function linkRootRuntimeBin(input) {
1497
- const cliPath = join13(input.repoRoot, "dist", "cli", "index.js");
1616
+ const cliPath = join14(input.repoRoot, "dist", "cli", "index.js");
1498
1617
  if (!await isFile2(cliPath))
1499
1618
  return null;
1500
- const nodeCliPath = join13(input.repoRoot, "dist", "cli-node", "index.js");
1619
+ const nodeCliPath = join14(input.repoRoot, "dist", "cli-node", "index.js");
1501
1620
  const platform = input.platform ?? process.platform;
1502
1621
  await mkdir5(input.binDir, { recursive: true });
1503
1622
  if (platform === "win32") {
1504
- const linkPath2 = join13(input.binDir, "omo.cmd");
1623
+ const linkPath2 = join14(input.binDir, "omo.cmd");
1505
1624
  await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
1506
1625
  return { name: "omo", path: linkPath2, target: cliPath };
1507
1626
  }
1508
- const linkPath = join13(input.binDir, "omo");
1627
+ const linkPath = join14(input.binDir, "omo");
1509
1628
  await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
1510
1629
  await chmod2(linkPath, 493);
1511
1630
  return { name: "omo", path: linkPath, target: cliPath };
1512
1631
  }
1513
1632
  async function linkCachedPluginBin(binDir, link, platform) {
1514
1633
  if (platform === "win32") {
1515
- const linkPath2 = join13(binDir, `${link.name}.cmd`);
1634
+ const linkPath2 = join14(binDir, `${link.name}.cmd`);
1516
1635
  await replaceCommandShim(linkPath2, link.target);
1517
1636
  return linkPath2;
1518
1637
  }
1519
- const linkPath = join13(binDir, link.name);
1638
+ const linkPath = join14(binDir, link.name);
1520
1639
  await replaceSymlink(linkPath, link.target);
1521
1640
  return linkPath;
1522
1641
  }
@@ -1535,16 +1654,16 @@ async function discoverPackageBins(root) {
1535
1654
  return links;
1536
1655
  }
1537
1656
  async function collectPackageBins(directory, root, links) {
1538
- const entries = await readdir3(directory, { withFileTypes: true });
1657
+ const entries = await readdir4(directory, { withFileTypes: true });
1539
1658
  if (entries.some((entry) => entry.isFile() && entry.name === "package.json")) {
1540
- await appendPackageBinLinks(join13(directory, "package.json"), directory, root, links);
1659
+ await appendPackageBinLinks(join14(directory, "package.json"), directory, root, links);
1541
1660
  }
1542
1661
  for (const entry of entries) {
1543
1662
  if (!entry.isDirectory())
1544
1663
  continue;
1545
1664
  if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist")
1546
1665
  continue;
1547
- const childPath = join13(directory, entry.name);
1666
+ const childPath = join14(directory, entry.name);
1548
1667
  if (!childPath.startsWith(root))
1549
1668
  continue;
1550
1669
  await collectPackageBins(childPath, root, links);
@@ -1603,17 +1722,17 @@ async function replaceSymlink(linkPath, targetPath) {
1603
1722
  async function replaceCommandShim(linkPath, targetPath) {
1604
1723
  if (await existingNonShim(linkPath))
1605
1724
  throw new Error(`${linkPath} already exists and is not a command shim`);
1606
- await writeFile4(linkPath, windowsCommandShim(targetPath));
1725
+ await writeFile5(linkPath, windowsCommandShim(targetPath));
1607
1726
  }
1608
1727
  async function replaceRuntimeWrapper(linkPath, content) {
1609
1728
  if (await existingNonRuntimeWrapper(linkPath))
1610
1729
  throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
1611
1730
  await rm9(linkPath, { force: true });
1612
- await writeFile4(linkPath, content);
1731
+ await writeFile5(linkPath, content);
1613
1732
  }
1614
1733
  async function existingNonRuntimeWrapper(path) {
1615
1734
  try {
1616
- const stat5 = await lstat6(path);
1735
+ const stat5 = await lstat7(path);
1617
1736
  if (stat5.isSymbolicLink())
1618
1737
  return false;
1619
1738
  if (!stat5.isFile())
@@ -1628,7 +1747,7 @@ async function existingNonRuntimeWrapper(path) {
1628
1747
  }
1629
1748
  async function existingNonShim(path) {
1630
1749
  try {
1631
- const stat5 = await lstat6(path);
1750
+ const stat5 = await lstat7(path);
1632
1751
  if (!stat5.isFile())
1633
1752
  return true;
1634
1753
  const content = await readFile8(path, "utf8");
@@ -1643,7 +1762,7 @@ async function existingNonShim(path) {
1643
1762
  }
1644
1763
  async function existingNonSymlink(path) {
1645
1764
  try {
1646
- const stat5 = await lstat6(path);
1765
+ const stat5 = await lstat7(path);
1647
1766
  if (!stat5.isSymbolicLink())
1648
1767
  return true;
1649
1768
  await readlink3(path);
@@ -1657,7 +1776,7 @@ async function existingNonSymlink(path) {
1657
1776
 
1658
1777
  // ../src/install/codex-config-toml.ts
1659
1778
  import { mkdir as mkdir6, readFile as readFile10 } from "node:fs/promises";
1660
- import { dirname as dirname7 } from "node:path";
1779
+ import { dirname as dirname8 } from "node:path";
1661
1780
 
1662
1781
  // ../src/install/toml-section-editor.ts
1663
1782
  function findTomlSection(config, header) {
@@ -1978,6 +2097,9 @@ function stripTomlLineComment(line) {
1978
2097
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE = ["codex-ultrawork-reviewer"];
1979
2098
  var CURRENT_MANAGED_CODEX_AGENT_NAMES = [
1980
2099
  "explorer",
2100
+ "lazycodex-worker-high",
2101
+ "lazycodex-worker-low",
2102
+ "lazycodex-worker-medium",
1981
2103
  "librarian",
1982
2104
  "metis",
1983
2105
  "momus",
@@ -2015,14 +2137,14 @@ function tomlKeySegment(value) {
2015
2137
  }
2016
2138
 
2017
2139
  // ../src/install/codex-config-atomic-write.ts
2018
- import { lstat as lstat7, readlink as readlink4, realpath, rename as rename3, unlink, writeFile as writeFile5 } from "node:fs/promises";
2019
- import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute4, join as join14, resolve as resolve5 } from "node:path";
2140
+ import { lstat as lstat8, readlink as readlink4, realpath, rename as rename3, unlink, writeFile as writeFile6 } from "node:fs/promises";
2141
+ import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute4, join as join15, resolve as resolve5 } from "node:path";
2020
2142
  var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
2021
2143
  var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
2022
2144
  async function writeFileAtomic(targetPath, data) {
2023
2145
  const writeTarget = await resolveSymlinkTarget(targetPath);
2024
- const temporaryPath = join14(dirname6(writeTarget), `.tmp-${basename5(writeTarget)}-${process.pid}-${Date.now()}`);
2025
- await writeFile5(temporaryPath, data);
2146
+ const temporaryPath = join15(dirname6(writeTarget), `.tmp-${basename5(writeTarget)}-${process.pid}-${Date.now()}`);
2147
+ await writeFile6(temporaryPath, data);
2026
2148
  try {
2027
2149
  await renameWithRetry(temporaryPath, writeTarget);
2028
2150
  } catch (error) {
@@ -2036,7 +2158,7 @@ async function writeFileAtomic(targetPath, data) {
2036
2158
  }
2037
2159
  async function resolveSymlinkTarget(targetPath) {
2038
2160
  try {
2039
- const linkStats = await lstat7(targetPath);
2161
+ const linkStats = await lstat8(targetPath);
2040
2162
  if (!linkStats.isSymbolicLink())
2041
2163
  return targetPath;
2042
2164
  } catch (error) {
@@ -2392,15 +2514,21 @@ function isRootSetting(line, key) {
2392
2514
 
2393
2515
  // ../src/install/codex-model-catalog.ts
2394
2516
  import { readFile as readFile9 } from "node:fs/promises";
2395
- import { join as join15 } from "node:path";
2517
+ import { join as join16 } from "node:path";
2396
2518
  var FALLBACK_CODEX_MODEL_CATALOG = {
2397
2519
  current: {
2398
- model: "gpt-5.5",
2399
- modelContextWindow: 400000,
2520
+ model: "gpt-5.6-sol",
2521
+ modelContextWindow: 372000,
2400
2522
  modelReasoningEffort: "high",
2401
2523
  planModeReasoningEffort: "xhigh"
2402
2524
  },
2403
2525
  managedProfiles: [
2526
+ {
2527
+ model: "gpt-5.5",
2528
+ modelContextWindow: 400000,
2529
+ modelReasoningEffort: "high",
2530
+ planModeReasoningEffort: "xhigh"
2531
+ },
2404
2532
  {
2405
2533
  model: "gpt-5.5",
2406
2534
  modelContextWindow: 1e6,
@@ -2411,7 +2539,7 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
2411
2539
  ]
2412
2540
  };
2413
2541
  async function readCodexModelCatalog(codexPackageRoot) {
2414
- const catalogPath = join15(codexPackageRoot, "plugin", "model-catalog.json");
2542
+ const catalogPath = join16(codexPackageRoot, "plugin", "model-catalog.json");
2415
2543
  try {
2416
2544
  const parsed = JSON.parse(await readFile9(catalogPath, "utf8"));
2417
2545
  return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
@@ -2494,30 +2622,87 @@ function isRootSetting2(line, key) {
2494
2622
  }
2495
2623
 
2496
2624
  // ../src/install/codex-multi-agent-v2-config.ts
2625
+ import { readFileSync } from "node:fs";
2626
+ import { dirname as dirname7, isAbsolute as isAbsolute5, join as join17 } from "node:path";
2497
2627
  var CODEX_AGENTS_HEADER = "agents";
2498
2628
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
2499
2629
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
2500
- function ensureCodexMultiAgentV2Config(config) {
2630
+ function ensureCodexMultiAgentV2Config(config, options = {}) {
2501
2631
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
2502
- const agentsConfig = ensureAgentsMaxThreads(featureFlag.config);
2503
- const section = findTomlSection(agentsConfig, CODEX_MULTI_AGENT_V2_HEADER);
2632
+ const v2Preferred = options.multiAgentVersion === "v2";
2633
+ const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
2634
+ const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
2504
2635
  const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
2636
+ const preserveDisable = featureFlag.value === false && !v2Preferred;
2637
+ const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
2638
+ const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
2505
2639
  if (!section) {
2506
- const enabledSetting = featureFlag.value === false ? `enabled = false
2640
+ const enabledSetting = preserveDisable ? `enabled = false
2507
2641
  ` : "";
2508
- return appendBlock(agentsConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
2642
+ return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
2509
2643
  ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
2510
2644
  `);
2511
2645
  }
2512
- const withPreservedDisable = featureFlag.value === false ? replaceOrInsertSetting(agentsConfig, section, "enabled", "false") : agentsConfig;
2513
- const updatedSection = featureFlag.value === false ? findTomlSection(withPreservedDisable, CODEX_MULTI_AGENT_V2_HEADER) : section;
2514
- if (!updatedSection) {
2515
- return appendBlock(withPreservedDisable, `[${CODEX_MULTI_AGENT_V2_HEADER}]
2516
- enabled = false
2517
- max_concurrent_threads_per_session = ${maxThreadsValue}
2518
- `);
2646
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
2647
+ }
2648
+ function resolveCodexMultiAgentVersion(config, configPath) {
2649
+ const model = readRootModel(config);
2650
+ if (model === null)
2651
+ return null;
2652
+ const catalogPath = resolveCatalogPath(readRootModelCatalogPath(config), configPath);
2653
+ const catalogVersion = readCatalogMultiAgentVersion(model, catalogPath);
2654
+ if (catalogVersion !== null)
2655
+ return catalogVersion;
2656
+ return /^gpt-5\.6\b/i.test(model) ? "v2" : null;
2657
+ }
2658
+ function resolveCatalogPath(configuredPath, configPath) {
2659
+ if (configuredPath === null)
2660
+ return join17(dirname7(configPath), "models_cache.json");
2661
+ return isAbsolute5(configuredPath) ? configuredPath : join17(dirname7(configPath), configuredPath);
2662
+ }
2663
+ function readCatalogMultiAgentVersion(model, cachePath) {
2664
+ let raw;
2665
+ try {
2666
+ raw = readFileSync(cachePath, "utf8");
2667
+ } catch {
2668
+ return null;
2669
+ }
2670
+ let cache;
2671
+ try {
2672
+ cache = JSON.parse(raw);
2673
+ } catch {
2674
+ return null;
2519
2675
  }
2520
- return replaceOrInsertSetting(withPreservedDisable, updatedSection, "max_concurrent_threads_per_session", maxThreadsValue);
2676
+ if (!isRecord2(cache) || !Array.isArray(cache.models))
2677
+ return null;
2678
+ for (const entry of cache.models) {
2679
+ if (!isRecord2(entry))
2680
+ continue;
2681
+ if (entry.slug !== model && entry.id !== model)
2682
+ continue;
2683
+ const version = entry.multi_agent_version;
2684
+ if (version === "v1" || version === "v2")
2685
+ return version;
2686
+ return null;
2687
+ }
2688
+ return null;
2689
+ }
2690
+ function readRootModel(config) {
2691
+ const double = config.match(/^\s*model\s*=\s*"([^"]+)"/m);
2692
+ if (double !== null)
2693
+ return double[1] ?? null;
2694
+ const single = config.match(/^\s*model\s*=\s*'([^']+)'/m);
2695
+ return single?.[1] ?? null;
2696
+ }
2697
+ function readRootModelCatalogPath(config) {
2698
+ const double = config.match(/^\s*model_catalog_json\s*=\s*"([^"]+)"/m);
2699
+ if (double !== null)
2700
+ return double[1] ?? null;
2701
+ const single = config.match(/^\s*model_catalog_json\s*=\s*'([^']+)'/m);
2702
+ return single?.[1] ?? null;
2703
+ }
2704
+ function isRecord2(value) {
2705
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2521
2706
  }
2522
2707
  function removeFeatureFlagSetting(config, featureName) {
2523
2708
  const section = findTomlSection(config, "features");
@@ -2538,6 +2723,36 @@ max_threads = ${maxThreadsValue}
2538
2723
  }
2539
2724
  return replaceOrInsertSetting(config, section, "max_threads", maxThreadsValue);
2540
2725
  }
2726
+ function removeAgentsMaxThreads(config) {
2727
+ const section = findTomlSection(config, CODEX_AGENTS_HEADER);
2728
+ if (!section)
2729
+ return config;
2730
+ if (!/^\s*max_threads\s*=/m.test(section.text))
2731
+ return config;
2732
+ return removeSetting(config, section, "max_threads");
2733
+ }
2734
+ function removeMultiAgentV2Disable(config) {
2735
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
2736
+ if (!section)
2737
+ return config;
2738
+ if (!/^\s*enabled\s*=\s*false(?:\s*#.*)?$/m.test(section.text))
2739
+ return config;
2740
+ return removeSetting(config, section, "enabled");
2741
+ }
2742
+ function setMultiAgentV2Disable(config) {
2743
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
2744
+ if (!section)
2745
+ return config;
2746
+ return replaceOrInsertSetting(config, section, "enabled", "false");
2747
+ }
2748
+ function raiseExistingAgentsMaxThreads(config) {
2749
+ const section = findTomlSection(config, CODEX_AGENTS_HEADER);
2750
+ if (!section)
2751
+ return config;
2752
+ if (!/^\s*max_threads\s*=/m.test(section.text))
2753
+ return config;
2754
+ return replaceOrInsertSetting(config, section, "max_threads", CODEX_SUBAGENT_THREAD_LIMIT.toString());
2755
+ }
2541
2756
  function readBooleanSetting(sectionText, key) {
2542
2757
  const match = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*(true|false)\\s*(?:#.*)?$`, "m").exec(sectionText);
2543
2758
  if (!match)
@@ -2547,7 +2762,7 @@ function readBooleanSetting(sectionText, key) {
2547
2762
 
2548
2763
  // ../src/install/codex-config-toml.ts
2549
2764
  async function updateCodexConfig(input) {
2550
- await mkdir6(dirname7(input.configPath), { recursive: true });
2765
+ await mkdir6(dirname8(input.configPath), { recursive: true });
2551
2766
  let config;
2552
2767
  try {
2553
2768
  config = await readFile10(input.configPath, "utf8");
@@ -2570,7 +2785,9 @@ async function updateCodexConfig(input) {
2570
2785
  config = ensureFeatureEnabled(config, "multi_agent");
2571
2786
  config = removeUnsupportedCodexMultiAgentModeConfig(config);
2572
2787
  config = ensureCodexReasoningConfig(config, await readCodexModelCatalog(input.repoRoot));
2573
- config = ensureCodexMultiAgentV2Config(config);
2788
+ config = ensureCodexMultiAgentV2Config(config, {
2789
+ multiAgentVersion: resolveCodexMultiAgentVersion(config, input.configPath)
2790
+ });
2574
2791
  if (input.autonomousPermissions === true)
2575
2792
  config = ensureAutonomousPermissions(config);
2576
2793
  if (!(input.preserveMarketplaceSource === true && hasMarketplaceBlock(config, input.marketplaceName))) {
@@ -2594,12 +2811,12 @@ function isMissingFileError(error) {
2594
2811
  }
2595
2812
 
2596
2813
  // ../src/install/codex-git-bash-mcp-env.ts
2597
- import { readFile as readFile11, writeFile as writeFile6 } from "node:fs/promises";
2598
- import { join as join16 } from "node:path";
2814
+ import { readFile as readFile11, writeFile as writeFile7 } from "node:fs/promises";
2815
+ import { join as join18 } from "node:path";
2599
2816
  var GIT_BASH_ENV_KEY = "OMO_CODEX_GIT_BASH_PATH";
2600
2817
  var CODEGRAPH_RELATIVE_ARGS = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
2601
2818
  async function stampGitBashMcpEnv(input) {
2602
- const manifestPath = join16(input.pluginRoot, ".mcp.json");
2819
+ const manifestPath = join18(input.pluginRoot, ".mcp.json");
2603
2820
  if (!await fileExistsStrict(manifestPath))
2604
2821
  return false;
2605
2822
  const parsed = JSON.parse(await readFile11(manifestPath, "utf8"));
@@ -2620,7 +2837,7 @@ async function stampGitBashMcpEnv(input) {
2620
2837
  }
2621
2838
  if (!changed)
2622
2839
  return false;
2623
- await writeFile6(manifestPath, `${JSON.stringify(parsed, null, "\t")}
2840
+ await writeFile7(manifestPath, `${JSON.stringify(parsed, null, "\t")}
2624
2841
  `);
2625
2842
  return true;
2626
2843
  }
@@ -2632,14 +2849,14 @@ function stampCodegraphMcpPath(mcpServers, pluginRoot) {
2632
2849
  const entrypoint = args[0];
2633
2850
  if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS.has(entrypoint))
2634
2851
  return false;
2635
- codegraphServer["args"] = [join16(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
2852
+ codegraphServer["args"] = [join18(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
2636
2853
  return true;
2637
2854
  }
2638
2855
 
2639
2856
  // ../src/install/codex-hook-trust.ts
2640
2857
  import { createHash as createHash3 } from "node:crypto";
2641
2858
  import { readFile as readFile12 } from "node:fs/promises";
2642
- import { join as join17 } from "node:path";
2859
+ import { join as join19 } from "node:path";
2643
2860
  var EVENT_LABELS = new Map([
2644
2861
  ["PreToolUse", "pre_tool_use"],
2645
2862
  ["PermissionRequest", "permission_request"],
@@ -2653,16 +2870,16 @@ var EVENT_LABELS = new Map([
2653
2870
  ["Stop", "stop"]
2654
2871
  ]);
2655
2872
  async function trustedHookStatesForPlugin(input) {
2656
- const manifestPath = join17(input.pluginRoot, ".codex-plugin", "plugin.json");
2657
- if (!await exists3(manifestPath))
2873
+ const manifestPath = join19(input.pluginRoot, ".codex-plugin", "plugin.json");
2874
+ if (!await exists4(manifestPath))
2658
2875
  return [];
2659
2876
  const manifest = JSON.parse(await readFile12(manifestPath, "utf8"));
2660
2877
  if (!isPlainRecord(manifest))
2661
2878
  return [];
2662
2879
  const states = [];
2663
2880
  for (const hookPath of hookManifestPaths(manifest.hooks)) {
2664
- const hooksPath = join17(input.pluginRoot, hookPath);
2665
- if (!await exists3(hooksPath))
2881
+ const hooksPath = join19(input.pluginRoot, hookPath);
2882
+ if (!await exists4(hooksPath))
2666
2883
  continue;
2667
2884
  const parsed = JSON.parse(await readFile12(hooksPath, "utf8"));
2668
2885
  if (!isPlainRecord(parsed) || !isPlainRecord(parsed.hooks))
@@ -2745,7 +2962,7 @@ function canonicalJson(value) {
2745
2962
  function stripDotSlash(value) {
2746
2963
  return value.startsWith("./") ? value.slice(2) : value;
2747
2964
  }
2748
- async function exists3(path) {
2965
+ async function exists4(path) {
2749
2966
  try {
2750
2967
  await readFile12(path, "utf8");
2751
2968
  return true;
@@ -2758,7 +2975,7 @@ async function exists3(path) {
2758
2975
 
2759
2976
  // ../src/install/codex-installer-bin-dir.ts
2760
2977
  import { homedir as homedir3 } from "node:os";
2761
- import { join as join18, resolve as resolve6 } from "node:path";
2978
+ import { join as join20, resolve as resolve6 } from "node:path";
2762
2979
  function resolveCodexInstallerBinDir(input) {
2763
2980
  const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
2764
2981
  if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
@@ -2767,7 +2984,7 @@ function resolveCodexInstallerBinDir(input) {
2767
2984
  const defaultCodexHome = resolve6(homeDir, ".codex");
2768
2985
  const resolvedCodexHome = resolve6(input.codexHome);
2769
2986
  if (resolvedCodexHome !== defaultCodexHome)
2770
- return join18(resolvedCodexHome, "bin");
2987
+ return join20(resolvedCodexHome, "bin");
2771
2988
  return resolve6(homeDir, ".local", "bin");
2772
2989
  }
2773
2990
 
@@ -2923,9 +3140,9 @@ async function resolveGitBashStep(options, degraded) {
2923
3140
  return false;
2924
3141
  }
2925
3142
  async function linkBundledAgentsStep(options) {
2926
- const agentsTarget = join19(options.codexHome, "agents");
3143
+ const agentsTarget = join21(options.codexHome, "agents");
2927
3144
  try {
2928
- const stageRoot = join19(options.pluginData, "bootstrap", "agents-stage");
3145
+ const stageRoot = join21(options.pluginData, "bootstrap", "agents-stage");
2929
3146
  await stageBundledAgents(options.pluginRoot, stageRoot);
2930
3147
  const preservedReasoning = await capturePreservedAgentReasoning({ codexHome: options.codexHome });
2931
3148
  const preservedServiceTier = await capturePreservedAgentServiceTier({ codexHome: options.codexHome });
@@ -2935,7 +3152,7 @@ async function linkBundledAgentsStep(options) {
2935
3152
  preservedReasoning,
2936
3153
  preservedServiceTier
2937
3154
  });
2938
- const agentConfigs = linked.map((link) => ({ configFile: `./agents/${link.name}`, name: agentNameFromToml2(link.name) })).sort((left, right) => left.name.localeCompare(right.name));
3155
+ const agentConfigs = linked.map((link) => ({ configFile: `./agents/${link.name}`, name: agentNameFromToml3(link.name) })).sort((left, right) => left.name.localeCompare(right.name));
2939
3156
  return { agentConfigs, degraded: [] };
2940
3157
  } catch (error) {
2941
3158
  return {
@@ -2953,21 +3170,21 @@ async function linkBundledAgentsStep(options) {
2953
3170
  async function stageBundledAgents(pluginRoot, stageRoot) {
2954
3171
  await rm10(stageRoot, { force: true, recursive: true });
2955
3172
  await mkdir7(stageRoot, { recursive: true });
2956
- const componentsRoot = join19(pluginRoot, "components");
3173
+ const componentsRoot = join21(pluginRoot, "components");
2957
3174
  for (const componentName of await directoryNames(componentsRoot)) {
2958
- const agentsDir = join19(componentsRoot, componentName, "agents");
3175
+ const agentsDir = join21(componentsRoot, componentName, "agents");
2959
3176
  const agentFiles = (await fileNames(agentsDir)).filter((name) => name.endsWith(".toml"));
2960
3177
  if (agentFiles.length === 0)
2961
3178
  continue;
2962
- const stagedAgentsDir = join19(stageRoot, "components", componentName, "agents");
3179
+ const stagedAgentsDir = join21(stageRoot, "components", componentName, "agents");
2963
3180
  await mkdir7(stagedAgentsDir, { recursive: true });
2964
3181
  for (const agentFile of agentFiles) {
2965
- await copyFile2(join19(agentsDir, agentFile), join19(stagedAgentsDir, agentFile));
3182
+ await copyFile2(join21(agentsDir, agentFile), join21(stagedAgentsDir, agentFile));
2966
3183
  }
2967
3184
  }
2968
3185
  }
2969
3186
  async function updateConfigStep(options, inputs, degraded) {
2970
- const configPath = join19(options.codexHome, "config.toml");
3187
+ const configPath = join21(options.codexHome, "config.toml");
2971
3188
  try {
2972
3189
  await assertWritableConfigIfPresent(configPath);
2973
3190
  const trustedHookStates = await trustedHookStatesForPlugin({
@@ -3023,7 +3240,7 @@ async function linkComponentBinsStep(options, degraded) {
3023
3240
  await linkRuntimeWrapperStep(options, binDir, degraded);
3024
3241
  }
3025
3242
  async function linkRuntimeWrapperStep(options, binDir, degraded) {
3026
- const cliPath = join19(options.pluginRoot, "dist", "cli", "index.js");
3243
+ const cliPath = join21(options.pluginRoot, "dist", "cli", "index.js");
3027
3244
  try {
3028
3245
  const linked = await linkRootRuntimeBin({
3029
3246
  binDir,
@@ -3056,7 +3273,7 @@ async function stampGitBashEnvStep(options, degraded) {
3056
3273
  degraded.push({
3057
3274
  component: "git-bash-env",
3058
3275
  hint: BOOTSTRAP_DOCTOR_HINT,
3059
- reason: `failed to stamp ${join19(options.pluginRoot, ".mcp.json")}: ${errorMessage(error)}`
3276
+ reason: `failed to stamp ${join21(options.pluginRoot, ".mcp.json")}: ${errorMessage(error)}`
3060
3277
  });
3061
3278
  }
3062
3279
  }
@@ -3068,7 +3285,7 @@ async function fileNames(root) {
3068
3285
  }
3069
3286
  async function entryNames(root, keep) {
3070
3287
  try {
3071
- const entries = await readdir4(root, { withFileTypes: true });
3288
+ const entries = await readdir5(root, { withFileTypes: true });
3072
3289
  return entries.filter((entry) => keep(entry)).map((entry) => entry.name).sort();
3073
3290
  } catch (error) {
3074
3291
  if (error instanceof Error && "code" in error && error.code === "ENOENT")
@@ -3076,7 +3293,7 @@ async function entryNames(root, keep) {
3076
3293
  throw error;
3077
3294
  }
3078
3295
  }
3079
- function agentNameFromToml2(fileName) {
3296
+ function agentNameFromToml3(fileName) {
3080
3297
  return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
3081
3298
  }
3082
3299
  function errorMessage(error) {
@@ -3124,11 +3341,11 @@ function resolvePluginDataRoot(env) {
3124
3341
  const fromEnv = env["PLUGIN_DATA"]?.trim();
3125
3342
  if (fromEnv !== undefined && fromEnv.length > 0)
3126
3343
  return fromEnv;
3127
- return join20(homedir4(), ".local", "share", "lazycodex");
3344
+ return join22(homedir4(), ".local", "share", "lazycodex");
3128
3345
  }
3129
3346
  async function readPluginVersion(pluginRoot) {
3130
3347
  try {
3131
- const parsed = JSON.parse(await readFile13(join20(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"));
3348
+ const parsed = JSON.parse(await readFile13(join22(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"));
3132
3349
  if (typeof parsed !== "object" || parsed === null)
3133
3350
  return;
3134
3351
  const version = parsed["version"];
@@ -3195,7 +3412,7 @@ async function runBootstrapWorker(options = {}) {
3195
3412
  degraded.push({
3196
3413
  component: "bootstrap",
3197
3414
  hint: BOOTSTRAP_DOCTOR_HINT,
3198
- reason: `plugin version unresolved from ${join20(pluginRoot, ".codex-plugin", "plugin.json")}`
3415
+ reason: `plugin version unresolved from ${join22(pluginRoot, ".codex-plugin", "plugin.json")}`
3199
3416
  });
3200
3417
  }
3201
3418
  for (const step of steps) {
@@ -3234,12 +3451,12 @@ function resolvePluginRoot(env) {
3234
3451
  const fromEnv = env["PLUGIN_ROOT"]?.trim();
3235
3452
  if (fromEnv !== undefined && fromEnv.length > 0)
3236
3453
  return fromEnv;
3237
- return resolve7(dirname8(fileURLToPath2(import.meta.url)), "..", "..", "..");
3454
+ return resolve7(dirname9(fileURLToPath2(import.meta.url)), "..", "..", "..");
3238
3455
  }
3239
3456
  async function appendBootstrapLog(pluginData, now, event, details) {
3240
3457
  try {
3241
- const logPath = join20(pluginData, "bootstrap", "bootstrap.log");
3242
- await mkdir8(dirname8(logPath), { recursive: true });
3458
+ const logPath = join22(pluginData, "bootstrap", "bootstrap.log");
3459
+ await mkdir8(dirname9(logPath), { recursive: true });
3243
3460
  await appendFile2(logPath, `${JSON.stringify({ timestamp: new Date(now).toISOString(), event, ...details })}
3244
3461
  `);
3245
3462
  } catch {}