oh-my-opencode 4.18.2 → 4.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/.agents/command/omomomo.md +1 -1
  2. package/.agents/skills/omomomo/SKILL.md +1 -1
  3. package/.opencode/command/omomomo.md +1 -1
  4. package/README.ja.md +6 -6
  5. package/README.ko.md +6 -6
  6. package/README.md +8 -8
  7. package/README.ru.md +6 -6
  8. package/README.zh-cn.md +6 -6
  9. package/dist/agents/atlas/agent.d.ts +7 -6
  10. package/dist/agents/gpt-prompt-identity.d.ts +3 -0
  11. package/dist/agents/sisyphus/gpt-5-5.d.ts +1 -1
  12. package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +1 -0
  13. package/dist/agents/sisyphus/index.d.ts +5 -0
  14. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  15. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  16. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  17. package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +2 -2
  18. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  19. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/index.js +781 -215
  22. package/dist/cli-node/index.js +781 -215
  23. package/dist/config/index.d.ts +1 -1
  24. package/dist/config/schema/agent-overrides.d.ts +48 -48
  25. package/dist/config/schema/browser-automation.d.ts +1 -0
  26. package/dist/config/schema/categories.d.ts +6 -6
  27. package/dist/config/schema/codegraph.d.ts +2 -0
  28. package/dist/config/schema/commands.d.ts +1 -3
  29. package/dist/config/schema/default-mode.d.ts +1 -1
  30. package/dist/config/schema/fallback-models.d.ts +5 -5
  31. package/dist/config/schema/goal.d.ts +7 -0
  32. package/dist/config/schema/hooks.d.ts +1 -1
  33. package/dist/config/schema/oh-my-opencode-config.d.ts +56 -58
  34. package/dist/config/schema/ralph-loop.d.ts +1 -1
  35. package/dist/config/schema.d.ts +1 -1
  36. package/dist/create-hooks.d.ts +1 -1
  37. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  38. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  39. package/dist/features/builtin-commands/types.d.ts +1 -1
  40. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  41. package/dist/hooks/codegraph-bootstrap/hook.d.ts +3 -2
  42. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  43. package/dist/hooks/goal/controller.d.ts +26 -0
  44. package/dist/hooks/goal/index.d.ts +23 -0
  45. package/dist/hooks/goal/prompt.d.ts +3 -0
  46. package/dist/hooks/goal/store.d.ts +8 -0
  47. package/dist/hooks/goal/tools.d.ts +10 -0
  48. package/dist/hooks/goal/types.d.ts +93 -0
  49. package/dist/hooks/goal/validation.d.ts +4 -0
  50. package/dist/hooks/index.d.ts +1 -0
  51. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  52. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  53. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  54. package/dist/hooks/start-work/notepad-scaffold.d.ts +10 -0
  55. package/dist/index.js +5398 -5109
  56. package/dist/oh-my-opencode.schema.json +34 -19
  57. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  58. package/dist/plugin/chat-message/types.d.ts +23 -10
  59. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  60. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  61. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  62. package/dist/plugin/stop-continuation.d.ts +2 -2
  63. package/dist/shared/omo-process-sweep.d.ts +18 -0
  64. package/dist/shared/system-directive.d.ts +0 -1
  65. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  66. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  67. package/dist/skills/ulw-plan/SKILL.md +31 -8
  68. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  69. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  70. package/dist/skills/ulw-research/SKILL.md +3 -3
  71. package/dist/testing/create-plugin-module.d.ts +1 -0
  72. package/dist/tools/delegate-task/types.d.ts +0 -1
  73. package/dist/tui.js +138 -80
  74. package/package.json +14 -14
  75. package/packages/git-bash-mcp/dist/cli.js +54 -8
  76. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +60 -0
  77. package/packages/lsp-core/src/lsp/client.ts +14 -1
  78. package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +2 -2
  79. package/packages/lsp-core/src/mcp.ts +9 -0
  80. package/packages/lsp-daemon/dist/cli.js +319 -51
  81. package/packages/lsp-daemon/dist/client.js +136 -48
  82. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
  83. package/packages/lsp-daemon/dist/daemon-client.js +4 -34
  84. package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
  85. package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
  86. package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
  87. package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
  88. package/packages/lsp-daemon/dist/daemon-server.js +5 -1
  89. package/packages/lsp-daemon/dist/index.js +137 -48
  90. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  91. package/packages/lsp-daemon/dist/proxy.js +1 -0
  92. package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
  93. package/packages/lsp-daemon/dist/version-reap.js +182 -0
  94. package/packages/lsp-tools-mcp/dist/cli.js +61 -10
  95. package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
  96. package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
  97. package/packages/lsp-tools-mcp/dist/tools.js +6 -1
  98. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  99. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
  100. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  101. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +22 -2
  103. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  104. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
  105. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
  106. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  107. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  108. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
  109. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
  110. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
  111. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
  112. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
  113. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
  114. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  115. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
  116. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
  117. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
  118. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
  119. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
  120. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
  121. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
  122. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
  123. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
  124. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
  125. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -0
  126. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  127. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  128. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  129. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  131. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  132. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  133. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
  135. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  136. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  137. package/packages/omo-codex/plugin/components/rules/dist/cli.js +11 -0
  138. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  139. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  140. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +11 -0
  141. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
  142. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  143. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  144. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  146. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  147. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  148. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  149. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  150. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  151. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  152. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  153. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  154. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  155. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  156. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  157. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
  158. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  159. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  160. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  161. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
  162. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  163. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  164. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  165. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  166. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
  168. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  169. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  170. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  171. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
  172. package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
  173. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
  174. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
  175. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
  176. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
  177. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  178. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  179. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +3 -3
  180. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
  181. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
  182. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
  191. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
  192. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
  193. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  194. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
  195. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
  196. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
  197. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
  202. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
  203. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -0
  204. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  206. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -6
  207. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
  208. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
  209. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
  211. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
  212. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
  213. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
  214. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
  216. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
  217. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
  218. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
  219. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
  220. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
  221. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
  222. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
  224. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
  225. package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
  226. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
  227. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
  228. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
  229. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
  230. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
  231. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
  232. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
  234. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
  235. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  236. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  237. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  238. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  239. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  240. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  241. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  242. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  243. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  244. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  245. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  246. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
  247. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  248. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -2
  249. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  250. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -2
  251. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  252. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  253. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  254. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  255. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  256. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  257. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  258. package/packages/omo-codex/plugin/package-lock.json +41 -41
  259. package/packages/omo-codex/plugin/package.json +1 -1
  260. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  261. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  262. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  263. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  264. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
  265. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  266. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
  267. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
  268. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  269. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  270. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
  271. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
  272. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
  273. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  274. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  275. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  276. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  277. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  278. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  279. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  280. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  281. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  282. package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
  283. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  284. package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +4 -1
  285. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  286. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  287. package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
  288. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  289. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  290. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  291. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  292. package/dist/skills/ultraresearch/SKILL.md +0 -10
  293. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  294. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  295. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  296. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  297. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  298. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  299. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  300. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  301. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  302. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  303. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  304. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  305. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  306. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  307. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -5903,7 +5903,7 @@ var package_default;
5903
5903
  var init_package = __esm(() => {
5904
5904
  package_default = {
5905
5905
  name: "@oh-my-opencode/omo-codex",
5906
- version: "4.18.2",
5906
+ version: "4.19.1",
5907
5907
  type: "module",
5908
5908
  private: true,
5909
5909
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -6429,7 +6429,7 @@ function whereCommand(command) {
6429
6429
  }
6430
6430
  }
6431
6431
  // packages/omo-codex/src/install/codex-process.ts
6432
- var WINDOWS_CMD_SHIM_COMMANDS = new Set(["npm", "npx"]);
6432
+ var WINDOWS_CMD_SHIM_COMMANDS = new Set(["codex", "npm", "npx"]);
6433
6433
  function resolveRunCommandInvocation(command, args, platform = process.platform) {
6434
6434
  if (platform !== "win32" || !WINDOWS_CMD_SHIM_COMMANDS.has(command.toLowerCase())) {
6435
6435
  return { command, args: [...args] };
@@ -7068,6 +7068,7 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
7068
7068
  const packageJsonPaths = [];
7069
7069
  await collectPackageJsonPaths(pluginRoot, pluginRoot, packageJsonPaths);
7070
7070
  const packageLock = await readPackageLock(pluginRoot);
7071
+ let rewroteAnyPackageJson = false;
7071
7072
  for (const packageJsonPath of packageJsonPaths) {
7072
7073
  const raw = await readFile5(packageJsonPath, "utf8");
7073
7074
  const parsed = JSON.parse(raw);
@@ -7103,13 +7104,16 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
7103
7104
  changed = true;
7104
7105
  }
7105
7106
  }
7106
- if (changed)
7107
+ if (changed) {
7107
7108
  await writeFile2(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
7108
7109
  `);
7110
+ rewroteAnyPackageJson = true;
7111
+ }
7109
7112
  }
7110
7113
  if (packageLock.changed)
7111
7114
  await writeFile2(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
7112
7115
  `);
7116
+ return rewroteAnyPackageJson;
7113
7117
  }
7114
7118
  async function readPackageLock(pluginRoot) {
7115
7119
  const path = join8(pluginRoot, "package-lock.json");
@@ -7530,10 +7534,11 @@ async function installCachedPlugin(input) {
7530
7534
  await rm4(tempPath, { recursive: true, force: true });
7531
7535
  try {
7532
7536
  await copyDirectory(input.sourcePath, tempPath);
7533
- await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
7537
+ const rewroteLocalFileDependencies = await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
7534
7538
  await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
7535
7539
  await copyRootRuntimeDists({ pluginRoot: tempPath, sourcePath: input.sourcePath });
7536
- await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, ["ci", "--omit=dev"]);
7540
+ const installArgs = rewroteLocalFileDependencies ? ["install", "--omit=dev", "--no-audit", "--no-fund"] : ["ci", "--omit=dev"];
7541
+ await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, installArgs);
7537
7542
  await removeCachedManagedNpmBinShims(tempPath);
7538
7543
  if (input.buildSource === false)
7539
7544
  await maybeRunNpmSyncSkills(tempPath, input.runCommand, env);
@@ -7837,9 +7842,16 @@ function findTomlSection(config, header) {
7837
7842
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7838
7843
  let offset = 0;
7839
7844
  let start = -1;
7845
+ let multilineQuote = null;
7840
7846
  for (const line of lines) {
7841
7847
  if (line.length === 0)
7842
7848
  break;
7849
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7850
+ multilineQuote = multilineScan.nextQuote;
7851
+ if (multilineScan.wasInside) {
7852
+ offset += line.length;
7853
+ continue;
7854
+ }
7843
7855
  const trimmed = line.trim();
7844
7856
  if (start === -1) {
7845
7857
  if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
@@ -7854,8 +7866,37 @@ function findTomlSection(config, header) {
7854
7866
  return { start, end: config.length, text: config.slice(start) };
7855
7867
  }
7856
7868
  function replaceOrInsertSetting(config, section, key, value) {
7857
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
7858
- const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
7869
+ const targetPath = parseTomlDottedKey(key);
7870
+ if (!targetPath)
7871
+ return config;
7872
+ const lines = section.text.match(/[^\n]*\n?|$/g) ?? [];
7873
+ let offset = 0;
7874
+ let multilineQuote = null;
7875
+ for (const line of lines) {
7876
+ if (line.length === 0)
7877
+ break;
7878
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7879
+ multilineQuote = multilineScan.nextQuote;
7880
+ if (multilineScan.wasInside) {
7881
+ offset += line.length;
7882
+ continue;
7883
+ }
7884
+ const assignmentIndex = findUnquotedAssignment(line);
7885
+ if (assignmentIndex < 0) {
7886
+ offset += line.length;
7887
+ continue;
7888
+ }
7889
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
7890
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
7891
+ offset += line.length;
7892
+ continue;
7893
+ }
7894
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
7895
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(section.text, offset + line.length, multilineScan.nextQuote) : offset + line.length;
7896
+ const sectionReplacement = section.text.slice(0, offset) + replacement2 + section.text.slice(assignmentEnd);
7897
+ return config.slice(0, section.start) + sectionReplacement + config.slice(section.end);
7898
+ }
7899
+ const replacement = insertSetting(section.text, key, value);
7859
7900
  return config.slice(0, section.start) + replacement + config.slice(section.end);
7860
7901
  }
7861
7902
  function removeSetting(config, section, key) {
@@ -7875,6 +7916,50 @@ function replaceOrInsertRootSetting(config, key, value) {
7875
7916
  return replacement;
7876
7917
  return `${replacement.trimEnd()}
7877
7918
 
7919
+ ${suffix.trimStart()}`;
7920
+ }
7921
+ function replaceOrInsertRootDottedSetting(config, keyPath, value) {
7922
+ const targetPath = parseTomlDottedKey(keyPath);
7923
+ if (!targetPath)
7924
+ return config;
7925
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7926
+ let offset = 0;
7927
+ let multilineQuote = null;
7928
+ for (const line of lines) {
7929
+ if (line.length === 0)
7930
+ break;
7931
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7932
+ multilineQuote = multilineScan.nextQuote;
7933
+ if (multilineScan.wasInside) {
7934
+ offset += line.length;
7935
+ continue;
7936
+ }
7937
+ if (isTomlTableHeaderLine(line))
7938
+ break;
7939
+ const assignmentIndex = findUnquotedAssignment(line);
7940
+ if (assignmentIndex < 0) {
7941
+ offset += line.length;
7942
+ continue;
7943
+ }
7944
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
7945
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
7946
+ offset += line.length;
7947
+ continue;
7948
+ }
7949
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
7950
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(config, offset + line.length, multilineScan.nextQuote) : offset + line.length;
7951
+ return config.slice(0, offset) + replacement2 + config.slice(assignmentEnd);
7952
+ }
7953
+ const sectionStart = findFirstTableStart(config);
7954
+ const root = config.slice(0, sectionStart).trimEnd();
7955
+ const suffix = config.slice(sectionStart);
7956
+ const replacement = `${root}${root.length > 0 ? `
7957
+ ` : ""}${keyPath} = ${value}
7958
+ `;
7959
+ if (suffix.length === 0)
7960
+ return replacement;
7961
+ return `${replacement.trimEnd()}
7962
+
7878
7963
  ${suffix.trimStart()}`;
7879
7964
  }
7880
7965
  function appendBlock(config, block) {
@@ -7887,9 +7972,16 @@ function appendBlock(config, block) {
7887
7972
  function findFirstTableStart(config) {
7888
7973
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7889
7974
  let offset = 0;
7975
+ let multilineQuote = null;
7890
7976
  for (const line of lines) {
7891
7977
  if (line.length === 0)
7892
7978
  break;
7979
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7980
+ multilineQuote = multilineScan.nextQuote;
7981
+ if (multilineScan.wasInside) {
7982
+ offset += line.length;
7983
+ continue;
7984
+ }
7893
7985
  if (isTomlTableHeaderLine(line))
7894
7986
  return offset;
7895
7987
  offset += line.length;
@@ -7927,6 +8019,131 @@ function isTomlTableHeaderLine(line) {
7927
8019
  const normalizedLine = stripUnquotedInlineComment(line).trim();
7928
8020
  return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
7929
8021
  }
8022
+ function scanTomlMultilineLine(line, currentQuote) {
8023
+ if (currentQuote) {
8024
+ return {
8025
+ wasInside: true,
8026
+ nextQuote: findTomlMultilineDelimiter(line, currentQuote, 0) === -1 ? currentQuote : null
8027
+ };
8028
+ }
8029
+ let quote = null;
8030
+ let index = 0;
8031
+ while (index < line.length) {
8032
+ const char = line[index];
8033
+ if (quote === '"') {
8034
+ if (char === "\\") {
8035
+ index += 2;
8036
+ continue;
8037
+ }
8038
+ if (char === '"')
8039
+ quote = null;
8040
+ index += 1;
8041
+ continue;
8042
+ }
8043
+ if (quote === "'") {
8044
+ if (char === "'")
8045
+ quote = null;
8046
+ index += 1;
8047
+ continue;
8048
+ }
8049
+ if (char === "#")
8050
+ break;
8051
+ const delimiter2 = line.startsWith('"""', index) ? '"""' : line.startsWith("'''", index) ? "'''" : null;
8052
+ if (delimiter2) {
8053
+ const closingIndex = findTomlMultilineDelimiter(line, delimiter2, index + delimiter2.length);
8054
+ return { wasInside: false, nextQuote: closingIndex === -1 ? delimiter2 : null };
8055
+ }
8056
+ if (char === '"' || char === "'")
8057
+ quote = char;
8058
+ index += 1;
8059
+ }
8060
+ return { wasInside: false, nextQuote: null };
8061
+ }
8062
+ function findTomlMultilineDelimiter(line, delimiter2, startIndex) {
8063
+ let index = line.indexOf(delimiter2, startIndex);
8064
+ while (index !== -1) {
8065
+ if (delimiter2 === "'''" || countPrecedingBackslashes(line, index) % 2 === 0)
8066
+ return index;
8067
+ index = line.indexOf(delimiter2, index + 1);
8068
+ }
8069
+ return -1;
8070
+ }
8071
+ function countPrecedingBackslashes(line, index) {
8072
+ let count = 0;
8073
+ let cursor = index - 1;
8074
+ while (cursor >= 0 && line[cursor] === "\\") {
8075
+ count += 1;
8076
+ cursor -= 1;
8077
+ }
8078
+ return count;
8079
+ }
8080
+ function findUnquotedAssignment(line) {
8081
+ return findUnquotedCharacter(line, "=", 0);
8082
+ }
8083
+ function findUnquotedComment(line, startIndex) {
8084
+ return findUnquotedCharacter(line, "#", startIndex);
8085
+ }
8086
+ function findUnquotedCharacter(line, target, startIndex) {
8087
+ let quote = null;
8088
+ let index = startIndex;
8089
+ while (index < line.length) {
8090
+ const char = line[index];
8091
+ if (quote === '"') {
8092
+ if (char === "\\") {
8093
+ index += 2;
8094
+ continue;
8095
+ }
8096
+ if (char === '"')
8097
+ quote = null;
8098
+ index += 1;
8099
+ continue;
8100
+ }
8101
+ if (quote === "'") {
8102
+ if (char === "'")
8103
+ quote = null;
8104
+ index += 1;
8105
+ continue;
8106
+ }
8107
+ if (char === '"' || char === "'") {
8108
+ quote = char;
8109
+ index += 1;
8110
+ continue;
8111
+ }
8112
+ if (char === target)
8113
+ return index;
8114
+ if (char === "#")
8115
+ return -1;
8116
+ index += 1;
8117
+ }
8118
+ return -1;
8119
+ }
8120
+ function tomlPathMatches(candidate, target) {
8121
+ return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
8122
+ }
8123
+ function replaceTomlAssignmentValue(line, assignmentIndex, value) {
8124
+ const newline = line.endsWith(`
8125
+ `) ? `
8126
+ ` : "";
8127
+ const lineBody = newline ? line.slice(0, -1) : line;
8128
+ const commentIndex = findUnquotedComment(lineBody, assignmentIndex + 1);
8129
+ const comment = commentIndex === -1 ? "" : ` ${lineBody.slice(commentIndex).trimStart()}`;
8130
+ return `${lineBody.slice(0, assignmentIndex + 1)} ${value}${comment}${newline}`;
8131
+ }
8132
+ function findTomlMultilineValueEnd(text, startOffset, quote) {
8133
+ const lines = text.slice(startOffset).match(/[^\n]*\n?|$/g) ?? [];
8134
+ let offset = startOffset;
8135
+ let currentQuote = quote;
8136
+ for (const line of lines) {
8137
+ if (line.length === 0)
8138
+ break;
8139
+ const scan = scanTomlMultilineLine(line, currentQuote);
8140
+ currentQuote = scan.nextQuote;
8141
+ offset += line.length;
8142
+ if (currentQuote === null)
8143
+ return offset;
8144
+ }
8145
+ return text.length;
8146
+ }
7930
8147
  function stripUnquotedInlineComment(line) {
7931
8148
  let quote = null;
7932
8149
  let index = 0;
@@ -8257,13 +8474,137 @@ function delay(milliseconds) {
8257
8474
  return new Promise((resolveDelay) => setTimeout(resolveDelay, milliseconds));
8258
8475
  }
8259
8476
 
8477
+ // packages/omo-codex/src/install/toml-setting-reader.ts
8478
+ function hasTomlSetting(config, keyPath) {
8479
+ const targetPath = parseTomlDottedKey(keyPath);
8480
+ if (!targetPath)
8481
+ return false;
8482
+ return hasTomlAssignment(config, (tablePath, settingPath) => {
8483
+ const fullPath = [...tablePath, ...settingPath];
8484
+ return fullPath.length === targetPath.length && fullPath.every((part, index) => part === targetPath[index]);
8485
+ });
8486
+ }
8487
+ function hasTomlRootDottedKeyPrefix(config, rootKey) {
8488
+ return hasTomlAssignment(config, (tablePath, settingPath) => tablePath.length === 0 && settingPath.length > 1 && settingPath[0] === rootKey);
8489
+ }
8490
+ function hasTomlAssignment(config, predicate) {
8491
+ let tablePath = [];
8492
+ let multilineQuote = null;
8493
+ for (const line of config.split(`
8494
+ `)) {
8495
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
8496
+ multilineQuote = multilineScan.nextQuote;
8497
+ if (multilineScan.wasInside)
8498
+ continue;
8499
+ const normalizedLine = stripUnquotedInlineComment2(line).trim();
8500
+ if (normalizedLine.length === 0)
8501
+ continue;
8502
+ const headerPath = parseTomlTableHeader2(normalizedLine);
8503
+ if (headerPath) {
8504
+ tablePath = headerPath;
8505
+ continue;
8506
+ }
8507
+ if (isTomlTableHeaderLine2(normalizedLine)) {
8508
+ tablePath = null;
8509
+ continue;
8510
+ }
8511
+ if (!tablePath)
8512
+ continue;
8513
+ const assignmentIndex = findUnquotedAssignment2(normalizedLine);
8514
+ if (assignmentIndex < 0)
8515
+ continue;
8516
+ const settingPath = parseTomlDottedKey(normalizedLine.slice(0, assignmentIndex).trim());
8517
+ if (!settingPath)
8518
+ continue;
8519
+ if (predicate(tablePath, settingPath))
8520
+ return true;
8521
+ }
8522
+ return false;
8523
+ }
8524
+ function parseTomlTableHeader2(line) {
8525
+ if (!line.startsWith("[") || !line.endsWith("]") || line.startsWith("[["))
8526
+ return null;
8527
+ return parseTomlDottedKey(line.slice(1, -1).trim());
8528
+ }
8529
+ function isTomlTableHeaderLine2(line) {
8530
+ return line.startsWith("[") && line.endsWith("]");
8531
+ }
8532
+ function stripUnquotedInlineComment2(line) {
8533
+ let quote = null;
8534
+ let index = 0;
8535
+ while (index < line.length) {
8536
+ const char = line[index];
8537
+ if (quote === '"') {
8538
+ if (char === "\\") {
8539
+ index += 2;
8540
+ continue;
8541
+ }
8542
+ if (char === '"')
8543
+ quote = null;
8544
+ index += 1;
8545
+ continue;
8546
+ }
8547
+ if (quote === "'") {
8548
+ if (char === "'")
8549
+ quote = null;
8550
+ index += 1;
8551
+ continue;
8552
+ }
8553
+ if (char === '"' || char === "'") {
8554
+ quote = char;
8555
+ index += 1;
8556
+ continue;
8557
+ }
8558
+ if (char === "#")
8559
+ return line.slice(0, index);
8560
+ index += 1;
8561
+ }
8562
+ return line;
8563
+ }
8564
+ function findUnquotedAssignment2(line) {
8565
+ let quote = null;
8566
+ let index = 0;
8567
+ while (index < line.length) {
8568
+ const char = line[index];
8569
+ if (quote === '"') {
8570
+ if (char === "\\") {
8571
+ index += 2;
8572
+ continue;
8573
+ }
8574
+ if (char === '"')
8575
+ quote = null;
8576
+ index += 1;
8577
+ continue;
8578
+ }
8579
+ if (quote === "'") {
8580
+ if (char === "'")
8581
+ quote = null;
8582
+ index += 1;
8583
+ continue;
8584
+ }
8585
+ if (char === '"' || char === "'") {
8586
+ quote = char;
8587
+ index += 1;
8588
+ continue;
8589
+ }
8590
+ if (char === "=")
8591
+ return index;
8592
+ index += 1;
8593
+ }
8594
+ return -1;
8595
+ }
8596
+
8260
8597
  // packages/omo-codex/src/install/codex-config-features.ts
8261
8598
  function ensureFeatureEnabled(config, featureName) {
8262
8599
  const section = findTomlSection(config, "features");
8263
- if (!section)
8600
+ if (!section) {
8601
+ if (hasTomlRootDottedKeyPrefix(config, "features")) {
8602
+ return replaceOrInsertRootDottedSetting(config, `features.${featureName}`, "true");
8603
+ }
8264
8604
  return appendBlock(config, `[features]
8265
8605
  ${featureName} = true
8266
8606
  `);
8607
+ }
8267
8608
  return replaceOrInsertSetting(config, section, featureName, "true");
8268
8609
  }
8269
8610
 
@@ -8331,7 +8672,7 @@ function ensureAutonomousPermissions(config) {
8331
8672
  next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
8332
8673
  next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
8333
8674
  for (const featureName of AUTONOMOUS_FEATURES) {
8334
- next = ensureFeatureEnabled2(next, featureName);
8675
+ next = ensureFeatureEnabled(next, featureName);
8335
8676
  }
8336
8677
  next = removeWindowsSandboxSetting(next);
8337
8678
  next = ensureNoticeEnabled(next, "hide_full_access_warning");
@@ -8349,14 +8690,6 @@ function ensureNoticeEnabled(config, key) {
8349
8690
  return appendNoticeBlock(config, key);
8350
8691
  return replaceOrInsertSetting(config, section, key, "true");
8351
8692
  }
8352
- function ensureFeatureEnabled2(config, key) {
8353
- const section = findTomlSection(config, "features");
8354
- if (section === null)
8355
- return appendBlock(config, `[features]
8356
- ${key} = true
8357
- `);
8358
- return replaceOrInsertSetting(config, section, key, "true");
8359
- }
8360
8693
  function appendNoticeBlock(config, key) {
8361
8694
  return appendBlock(config, `[notice]
8362
8695
  ${key} = true
@@ -8428,7 +8761,7 @@ function readStringArraySetting(sectionText, key) {
8428
8761
  const assignmentIndex = line.indexOf("=");
8429
8762
  if (assignmentIndex === -1)
8430
8763
  return null;
8431
- return parseTomlStringArray(stripUnquotedInlineComment2(line.slice(assignmentIndex + 1)).trim());
8764
+ return parseTomlStringArray(stripUnquotedInlineComment3(line.slice(assignmentIndex + 1)).trim());
8432
8765
  }
8433
8766
  return null;
8434
8767
  }
@@ -8472,7 +8805,7 @@ function parseTomlString(input, startIndex) {
8472
8805
  }
8473
8806
  return null;
8474
8807
  }
8475
- function stripUnquotedInlineComment2(line) {
8808
+ function stripUnquotedInlineComment3(line) {
8476
8809
  let quote = null;
8477
8810
  let index = 0;
8478
8811
  while (index < line.length) {
@@ -8686,24 +9019,27 @@ import { readFileSync } from "node:fs";
8686
9019
  import { dirname as dirname7, isAbsolute as isAbsolute6, join as join18 } from "node:path";
8687
9020
  var CODEX_AGENTS_HEADER = "agents";
8688
9021
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
9022
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY = `${CODEX_MULTI_AGENT_V2_HEADER}.max_concurrent_threads_per_session`;
8689
9023
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
9024
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT = 16;
8690
9025
  function ensureCodexMultiAgentV2Config(config, options = {}) {
8691
9026
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
8692
9027
  const v2Preferred = options.multiAgentVersion === "v2";
8693
9028
  const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
8694
9029
  const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
8695
- const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
8696
9030
  const preserveDisable = featureFlag.value === false && !v2Preferred;
8697
9031
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
9032
+ if (hasTomlSetting(featureConfig, CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY))
9033
+ return featureConfig;
8698
9034
  const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
8699
9035
  if (!section) {
8700
9036
  const enabledSetting = preserveDisable ? `enabled = false
8701
9037
  ` : "";
8702
9038
  return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
8703
- ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
9039
+ ${enabledSetting}max_concurrent_threads_per_session = ${CODEX_MULTI_AGENT_V2_THREAD_LIMIT}
8704
9040
  `);
8705
9041
  }
8706
- return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
9042
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", CODEX_MULTI_AGENT_V2_THREAD_LIMIT.toString());
8707
9043
  }
8708
9044
  function resolveCodexMultiAgentVersion(config, configPath) {
8709
9045
  const model = readRootModel(config);
@@ -9061,6 +9397,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9061
9397
  {
9062
9398
  previous: { model: "gpt-5.5", effort: "xhigh" },
9063
9399
  current: { model: "gpt-5.6-sol", effort: "ultra" }
9400
+ },
9401
+ {
9402
+ previous: { model: "gpt-5.6-sol", effort: "ultra" },
9403
+ current: { model: "gpt-5.6-terra", effort: "high" }
9064
9404
  }
9065
9405
  ]
9066
9406
  ],
@@ -9070,6 +9410,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9070
9410
  {
9071
9411
  previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9072
9412
  current: { model: "gpt-5.6-sol", effort: "max" }
9413
+ },
9414
+ {
9415
+ previous: { model: "gpt-5.6-sol", effort: "max" },
9416
+ current: { model: "gpt-5.6-sol", effort: "high" }
9073
9417
  }
9074
9418
  ]
9075
9419
  ],
@@ -9079,6 +9423,37 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9079
9423
  {
9080
9424
  previous: { model: "gpt-5.6-sol", effort: "high" },
9081
9425
  current: { model: "gpt-5.6-luna", effort: "max" }
9426
+ },
9427
+ {
9428
+ previous: { model: "gpt-5.6-luna", effort: "max" },
9429
+ current: { model: "gpt-5.6-terra", effort: "high" }
9430
+ }
9431
+ ]
9432
+ ],
9433
+ [
9434
+ "lazycodex-worker-high",
9435
+ [
9436
+ {
9437
+ previous: { model: "gpt-5.6-sol", effort: "max" },
9438
+ current: { model: "gpt-5.6-sol", effort: "medium" }
9439
+ }
9440
+ ]
9441
+ ],
9442
+ [
9443
+ "lazycodex-code-reviewer",
9444
+ [
9445
+ {
9446
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9447
+ current: { model: "gpt-5.6-terra", effort: "medium" }
9448
+ }
9449
+ ]
9450
+ ],
9451
+ [
9452
+ "lazycodex-clone-fidelity-reviewer",
9453
+ [
9454
+ {
9455
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9456
+ current: { model: "gpt-5.6-terra", effort: "high" }
9082
9457
  }
9083
9458
  ]
9084
9459
  ],
@@ -9097,6 +9472,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9097
9472
  {
9098
9473
  previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9099
9474
  current: { model: "gpt-5.6-sol", effort: "high" }
9475
+ },
9476
+ {
9477
+ previous: { model: "gpt-5.6-sol", effort: "high" },
9478
+ current: { model: "gpt-5.6-sol", effort: "low" }
9100
9479
  }
9101
9480
  ]
9102
9481
  ]
@@ -75,7 +75,44 @@ test("#given no root model #when generated bundle updates config #then it does n
75
75
  // then
76
76
  const config = await readFile(configPath, "utf8");
77
77
  assert.doesNotMatch(config, /^\s*max_threads\s*=/m);
78
- assert.match(config, /max_concurrent_threads_per_session = 1000/);
78
+ assert.match(config, /max_concurrent_threads_per_session = 16/);
79
+ });
80
+
81
+ test("#given an inline-commented V2 thread cap #when generated bundle updates config twice #then preserves the line and ordering byte-for-byte", async () => {
82
+ // given
83
+ const root = await mkdtemp(join(tmpdir(), "omo-codex-generated-explicit-v2-cap-"));
84
+ const configPath = join(root, "config.toml");
85
+ await writeFile(
86
+ configPath,
87
+ [
88
+ "[features.multi_agent_v2]",
89
+ "usage_hint_enabled = false",
90
+ "max_concurrent_threads_per_session = 7 # user cap",
91
+ "show_tool_use = false",
92
+ "",
93
+ ].join("\n"),
94
+ );
95
+
96
+ // when
97
+ const updateInput = {
98
+ configPath,
99
+ repoRoot: "/repo/packages/omo-codex",
100
+ marketplaceName: "debug",
101
+ marketplaceSource: { sourceType: "local", source: "/repo/packages/omo-codex" },
102
+ pluginNames: ["omo"],
103
+ };
104
+ await updateCodexConfig(updateInput);
105
+ const firstPass = await readFile(configPath, "utf8");
106
+ const firstV2Section = sectionText(firstPass, "[features.multi_agent_v2]");
107
+ await updateCodexConfig(updateInput);
108
+
109
+ // then
110
+ const secondPass = await readFile(configPath, "utf8");
111
+ assert.equal(sectionText(secondPass, "[features.multi_agent_v2]"), firstV2Section);
112
+ assert.match(
113
+ sectionText(secondPass, "[features.multi_agent_v2]"),
114
+ /usage_hint_enabled = false\nmax_concurrent_threads_per_session = 7 # user cap\nshow_tool_use = false/,
115
+ );
79
116
  });
80
117
 
81
118
  test("#given explicit v1 model_catalog_json and stale models_cache v2 #when generated bundle updates config #then explicit catalog preserves disable and cap", async () => {
@@ -153,7 +190,7 @@ test("#given explicit v2 model_catalog_json and stale models_cache v1 #when gene
153
190
  const v2Section = sectionText(config, "[features.multi_agent_v2]");
154
191
  assert.doesNotMatch(v2Section, /^enabled\s*=/m);
155
192
  assert.doesNotMatch(config, /^\s*max_threads\s*=/m);
156
- assert.match(v2Section, /max_concurrent_threads_per_session = 1000/);
193
+ assert.match(v2Section, /max_concurrent_threads_per_session = 16/);
157
194
  });
158
195
 
159
196
  function sectionText(config, header) {
@@ -94,7 +94,10 @@ test("#given local marketplace #when installing #then copies versioned plugins a
94
94
  ["npm", "run build", pluginRoot],
95
95
  ]);
96
96
  assert.equal(commandLog[2][0], "npm");
97
- assert.equal(commandLog[2][1], "ci --omit=dev");
97
+ // The @example/shared-lsp file: dep points outside the plugin, so the cache
98
+ // installer rewrites package.json and switches to `npm install` to avoid the
99
+ // npm ci lock-desync (lazycodex#137).
100
+ assert.equal(commandLog[2][1], "install --omit=dev --no-audit --no-fund");
98
101
  assert.equal(commandLog[2][2].startsWith(join(codexHome, "plugins", "cache", "debug-marketplace", "alpha", ".tmp-1.2.3-")), true);
99
102
 
100
103
  const config = await readFile(join(codexHome, "config.toml"), "utf8");