oh-my-codex 0.15.0 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (533) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +36 -5
  4. package/crates/omx-explore/src/main.rs +222 -12
  5. package/dist/agents/__tests__/native-config.test.js +40 -0
  6. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  7. package/dist/agents/native-config.d.ts +1 -0
  8. package/dist/agents/native-config.d.ts.map +1 -1
  9. package/dist/agents/native-config.js +6 -1
  10. package/dist/agents/native-config.js.map +1 -1
  11. package/dist/agents/policy.d.ts +1 -0
  12. package/dist/agents/policy.d.ts.map +1 -1
  13. package/dist/agents/policy.js +4 -0
  14. package/dist/agents/policy.js.map +1 -1
  15. package/dist/cli/__tests__/autoresearch-guided.test.js +37 -13
  16. package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
  17. package/dist/cli/__tests__/codex-plugin-layout.test.js +1 -1
  18. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  19. package/dist/cli/__tests__/doctor-team.test.js +46 -1
  20. package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
  21. package/dist/cli/__tests__/doctor-warning-copy.test.js +225 -111
  22. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  23. package/dist/cli/__tests__/exec.test.js +96 -1
  24. package/dist/cli/__tests__/exec.test.js.map +1 -1
  25. package/dist/cli/__tests__/explore.test.js +15 -2
  26. package/dist/cli/__tests__/explore.test.js.map +1 -1
  27. package/dist/cli/__tests__/index.test.js +292 -3
  28. package/dist/cli/__tests__/index.test.js.map +1 -1
  29. package/dist/cli/__tests__/launch-fallback.test.js +223 -0
  30. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  31. package/dist/cli/__tests__/mcp-parity.test.js +86 -0
  32. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  33. package/dist/cli/__tests__/package-bin-contract.test.js +23 -0
  34. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  35. package/dist/cli/__tests__/question.test.js +76 -11
  36. package/dist/cli/__tests__/question.test.js.map +1 -1
  37. package/dist/cli/__tests__/setup-agents-overwrite.test.js +140 -1
  38. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  39. package/dist/cli/__tests__/setup-install-mode.test.js +310 -4
  40. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  41. package/dist/cli/__tests__/setup-prompts-overwrite.test.js +78 -19
  42. package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
  43. package/dist/cli/__tests__/setup-refresh.test.js +79 -2
  44. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  45. package/dist/cli/__tests__/sidecar.test.d.ts +2 -0
  46. package/dist/cli/__tests__/sidecar.test.d.ts.map +1 -0
  47. package/dist/cli/__tests__/sidecar.test.js +24 -0
  48. package/dist/cli/__tests__/sidecar.test.js.map +1 -0
  49. package/dist/cli/__tests__/team.test.js +54 -7
  50. package/dist/cli/__tests__/team.test.js.map +1 -1
  51. package/dist/cli/autoresearch-guided.d.ts.map +1 -1
  52. package/dist/cli/autoresearch-guided.js +12 -4
  53. package/dist/cli/autoresearch-guided.js.map +1 -1
  54. package/dist/cli/codex-home.d.ts +4 -6
  55. package/dist/cli/codex-home.d.ts.map +1 -1
  56. package/dist/cli/codex-home.js +9 -41
  57. package/dist/cli/codex-home.js.map +1 -1
  58. package/dist/cli/doctor.d.ts +1 -1
  59. package/dist/cli/doctor.d.ts.map +1 -1
  60. package/dist/cli/doctor.js +509 -279
  61. package/dist/cli/doctor.js.map +1 -1
  62. package/dist/cli/index.d.ts +6 -4
  63. package/dist/cli/index.d.ts.map +1 -1
  64. package/dist/cli/index.js +284 -25
  65. package/dist/cli/index.js.map +1 -1
  66. package/dist/cli/omx.js +3 -1
  67. package/dist/cli/omx.js.map +1 -1
  68. package/dist/cli/plugin-marketplace.d.ts +13 -0
  69. package/dist/cli/plugin-marketplace.d.ts.map +1 -0
  70. package/dist/cli/plugin-marketplace.js +77 -0
  71. package/dist/cli/plugin-marketplace.js.map +1 -0
  72. package/dist/cli/question.d.ts +1 -1
  73. package/dist/cli/question.d.ts.map +1 -1
  74. package/dist/cli/question.js +26 -12
  75. package/dist/cli/question.js.map +1 -1
  76. package/dist/cli/setup-preferences.d.ts +20 -0
  77. package/dist/cli/setup-preferences.d.ts.map +1 -0
  78. package/dist/cli/setup-preferences.js +71 -0
  79. package/dist/cli/setup-preferences.js.map +1 -0
  80. package/dist/cli/setup.d.ts +7 -5
  81. package/dist/cli/setup.d.ts.map +1 -1
  82. package/dist/cli/setup.js +271 -152
  83. package/dist/cli/setup.js.map +1 -1
  84. package/dist/cli/team.d.ts +1 -0
  85. package/dist/cli/team.d.ts.map +1 -1
  86. package/dist/cli/team.js +70 -15
  87. package/dist/cli/team.js.map +1 -1
  88. package/dist/config/__tests__/generator-idempotent.test.js +100 -3
  89. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  90. package/dist/config/__tests__/generator-notify.test.js +6 -5
  91. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  92. package/dist/config/__tests__/generator-status-line-presets.test.d.ts +2 -0
  93. package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +1 -0
  94. package/dist/config/__tests__/generator-status-line-presets.test.js +203 -0
  95. package/dist/config/__tests__/generator-status-line-presets.test.js.map +1 -0
  96. package/dist/config/__tests__/models.test.js +23 -1
  97. package/dist/config/__tests__/models.test.js.map +1 -1
  98. package/dist/config/generator.d.ts +9 -1
  99. package/dist/config/generator.d.ts.map +1 -1
  100. package/dist/config/generator.js +184 -16
  101. package/dist/config/generator.js.map +1 -1
  102. package/dist/config/models.d.ts +5 -1
  103. package/dist/config/models.d.ts.map +1 -1
  104. package/dist/config/models.js +12 -2
  105. package/dist/config/models.js.map +1 -1
  106. package/dist/exec/followup.d.ts +44 -0
  107. package/dist/exec/followup.d.ts.map +1 -0
  108. package/dist/exec/followup.js +349 -0
  109. package/dist/exec/followup.js.map +1 -0
  110. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts +2 -0
  111. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts.map +1 -0
  112. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +37 -0
  113. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -0
  114. package/dist/hooks/__tests__/codebase-map.test.js +63 -1
  115. package/dist/hooks/__tests__/codebase-map.test.js.map +1 -1
  116. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +1 -1
  117. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +5 -5
  118. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
  119. package/dist/hooks/__tests__/deep-interview-contract.test.js +12 -9
  120. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
  121. package/dist/hooks/__tests__/keyword-detector.test.js +25 -18
  122. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  123. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -2
  124. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  125. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +45 -2
  126. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  127. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +17 -0
  128. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  129. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +121 -0
  130. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
  131. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +4 -4
  132. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  133. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +103 -0
  134. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  135. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +2 -2
  136. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  137. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +27 -13
  138. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  139. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts +2 -0
  140. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +1 -0
  141. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +35 -0
  142. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -0
  143. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +215 -0
  144. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  145. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +70 -3
  146. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  147. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +5 -0
  148. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
  149. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +3 -2
  150. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +1 -1
  151. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +9 -0
  152. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
  153. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +2 -0
  154. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +1 -0
  155. package/dist/hooks/__tests__/prompt-refactor-contract.test.js +22 -0
  156. package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +1 -0
  157. package/dist/hooks/codebase-map.d.ts.map +1 -1
  158. package/dist/hooks/codebase-map.js +83 -6
  159. package/dist/hooks/codebase-map.js.map +1 -1
  160. package/dist/hooks/keyword-detector.d.ts +1 -1
  161. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  162. package/dist/hooks/keyword-detector.js +35 -4
  163. package/dist/hooks/keyword-detector.js.map +1 -1
  164. package/dist/hooks/prompt-guidance-contract.d.ts +6 -0
  165. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  166. package/dist/hooks/prompt-guidance-contract.js +117 -13
  167. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  168. package/dist/hooks/session.d.ts +2 -0
  169. package/dist/hooks/session.d.ts.map +1 -1
  170. package/dist/hooks/session.js +6 -0
  171. package/dist/hooks/session.js.map +1 -1
  172. package/dist/hud/__tests__/index.test.js +4 -4
  173. package/dist/hud/__tests__/index.test.js.map +1 -1
  174. package/dist/hud/__tests__/state.test.js +4 -0
  175. package/dist/hud/__tests__/state.test.js.map +1 -1
  176. package/dist/hud/__tests__/types.test.js +27 -0
  177. package/dist/hud/__tests__/types.test.js.map +1 -1
  178. package/dist/hud/state.d.ts.map +1 -1
  179. package/dist/hud/state.js +8 -0
  180. package/dist/hud/state.js.map +1 -1
  181. package/dist/hud/types.d.ts +9 -0
  182. package/dist/hud/types.d.ts.map +1 -1
  183. package/dist/hud/types.js +3 -0
  184. package/dist/hud/types.js.map +1 -1
  185. package/dist/mcp/__tests__/bootstrap.test.js +23 -5
  186. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
  187. package/dist/mcp/__tests__/server-lifecycle.test.js +50 -7
  188. package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
  189. package/dist/mcp/__tests__/state-server.test.js +70 -12
  190. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  191. package/dist/mcp/bootstrap.d.ts +10 -1
  192. package/dist/mcp/bootstrap.d.ts.map +1 -1
  193. package/dist/mcp/bootstrap.js +71 -26
  194. package/dist/mcp/bootstrap.js.map +1 -1
  195. package/dist/mcp/state-server.d.ts +5 -11
  196. package/dist/mcp/state-server.d.ts.map +1 -1
  197. package/dist/mcp/state-server.js +16 -432
  198. package/dist/mcp/state-server.js.map +1 -1
  199. package/dist/modes/__tests__/base-autoresearch-contract.test.js +1 -1
  200. package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
  201. package/dist/pipeline/__tests__/orchestrator.test.js +89 -5
  202. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  203. package/dist/pipeline/__tests__/stages.test.js +98 -1
  204. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  205. package/dist/pipeline/index.d.ts +5 -3
  206. package/dist/pipeline/index.d.ts.map +1 -1
  207. package/dist/pipeline/index.js +4 -3
  208. package/dist/pipeline/index.js.map +1 -1
  209. package/dist/pipeline/orchestrator.d.ts +7 -6
  210. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  211. package/dist/pipeline/orchestrator.js +90 -11
  212. package/dist/pipeline/orchestrator.js.map +1 -1
  213. package/dist/pipeline/review-verdict.d.ts +3 -0
  214. package/dist/pipeline/review-verdict.d.ts.map +1 -0
  215. package/dist/pipeline/review-verdict.js +14 -0
  216. package/dist/pipeline/review-verdict.js.map +1 -0
  217. package/dist/pipeline/stages/code-review.d.ts +33 -0
  218. package/dist/pipeline/stages/code-review.d.ts.map +1 -0
  219. package/dist/pipeline/stages/code-review.js +51 -0
  220. package/dist/pipeline/stages/code-review.js.map +1 -0
  221. package/dist/pipeline/stages/ralph-verify.d.ts +12 -2
  222. package/dist/pipeline/stages/ralph-verify.d.ts.map +1 -1
  223. package/dist/pipeline/stages/ralph-verify.js +24 -6
  224. package/dist/pipeline/stages/ralph-verify.js.map +1 -1
  225. package/dist/pipeline/stages/ralplan.d.ts +1 -1
  226. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  227. package/dist/pipeline/stages/ralplan.js +21 -1
  228. package/dist/pipeline/stages/ralplan.js.map +1 -1
  229. package/dist/pipeline/types.d.ts +14 -7
  230. package/dist/pipeline/types.d.ts.map +1 -1
  231. package/dist/pipeline/types.js +2 -2
  232. package/dist/planning/__tests__/artifacts.test.js +152 -1
  233. package/dist/planning/__tests__/artifacts.test.js.map +1 -1
  234. package/dist/planning/artifacts.d.ts +9 -0
  235. package/dist/planning/artifacts.d.ts.map +1 -1
  236. package/dist/planning/artifacts.js +60 -1
  237. package/dist/planning/artifacts.js.map +1 -1
  238. package/dist/question/__tests__/client.test.js +23 -3
  239. package/dist/question/__tests__/client.test.js.map +1 -1
  240. package/dist/question/__tests__/renderer.test.js +148 -37
  241. package/dist/question/__tests__/renderer.test.js.map +1 -1
  242. package/dist/question/__tests__/types.test.js +21 -0
  243. package/dist/question/__tests__/types.test.js.map +1 -1
  244. package/dist/question/__tests__/ui.test.js +155 -7
  245. package/dist/question/__tests__/ui.test.js.map +1 -1
  246. package/dist/question/client.d.ts +14 -4
  247. package/dist/question/client.d.ts.map +1 -1
  248. package/dist/question/client.js.map +1 -1
  249. package/dist/question/renderer.d.ts +11 -1
  250. package/dist/question/renderer.d.ts.map +1 -1
  251. package/dist/question/renderer.js +102 -7
  252. package/dist/question/renderer.js.map +1 -1
  253. package/dist/question/state.d.ts +2 -2
  254. package/dist/question/state.d.ts.map +1 -1
  255. package/dist/question/state.js +26 -17
  256. package/dist/question/state.js.map +1 -1
  257. package/dist/question/types.d.ts +25 -1
  258. package/dist/question/types.d.ts.map +1 -1
  259. package/dist/question/types.js +48 -13
  260. package/dist/question/types.js.map +1 -1
  261. package/dist/question/ui.d.ts +15 -2
  262. package/dist/question/ui.d.ts.map +1 -1
  263. package/dist/question/ui.js +268 -162
  264. package/dist/question/ui.js.map +1 -1
  265. package/dist/scripts/__tests__/codex-native-hook.test.js +415 -94
  266. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  267. package/dist/scripts/__tests__/generate-release-body.test.js +36 -0
  268. package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
  269. package/dist/scripts/__tests__/prompt-inventory.test.d.ts +2 -0
  270. package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +1 -0
  271. package/dist/scripts/__tests__/prompt-inventory.test.js +56 -0
  272. package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -0
  273. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  274. package/dist/scripts/codex-native-hook.js +232 -54
  275. package/dist/scripts/codex-native-hook.js.map +1 -1
  276. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  277. package/dist/scripts/codex-native-pre-post.js +12 -9
  278. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  279. package/dist/scripts/generate-release-body.d.ts.map +1 -1
  280. package/dist/scripts/generate-release-body.js +12 -3
  281. package/dist/scripts/generate-release-body.js.map +1 -1
  282. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +2 -0
  283. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +1 -0
  284. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +153 -0
  285. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +1 -0
  286. package/dist/scripts/notify-hook/managed-tmux.d.ts +4 -2
  287. package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
  288. package/dist/scripts/notify-hook/managed-tmux.js +188 -6
  289. package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
  290. package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
  291. package/dist/scripts/notify-hook/process-runner.js +7 -3
  292. package/dist/scripts/notify-hook/process-runner.js.map +1 -1
  293. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  294. package/dist/scripts/notify-hook/team-dispatch.js +96 -11
  295. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  296. package/dist/scripts/notify-hook/team-tmux-guard.js +3 -3
  297. package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts +34 -0
  298. package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts.map +1 -0
  299. package/dist/scripts/notify-hook/team-worker-posttooluse.js +434 -0
  300. package/dist/scripts/notify-hook/team-worker-posttooluse.js.map +1 -0
  301. package/dist/scripts/notify-hook/team-worker.d.ts +1 -1
  302. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  303. package/dist/scripts/notify-hook/team-worker.js +3 -43
  304. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  305. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  306. package/dist/scripts/notify-hook/tmux-injection.js +25 -4
  307. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  308. package/dist/scripts/notify-hook.js +36 -5
  309. package/dist/scripts/notify-hook.js.map +1 -1
  310. package/dist/scripts/prompt-inventory.d.ts +29 -0
  311. package/dist/scripts/prompt-inventory.d.ts.map +1 -0
  312. package/dist/scripts/prompt-inventory.js +178 -0
  313. package/dist/scripts/prompt-inventory.js.map +1 -0
  314. package/dist/scripts/run-test-files.js +1 -0
  315. package/dist/scripts/run-test-files.js.map +1 -1
  316. package/dist/sidecar/__tests__/boundary.test.d.ts +2 -0
  317. package/dist/sidecar/__tests__/boundary.test.d.ts.map +1 -0
  318. package/dist/sidecar/__tests__/boundary.test.js +48 -0
  319. package/dist/sidecar/__tests__/boundary.test.js.map +1 -0
  320. package/dist/sidecar/__tests__/collector.test.d.ts +2 -0
  321. package/dist/sidecar/__tests__/collector.test.d.ts.map +1 -0
  322. package/dist/sidecar/__tests__/collector.test.js +162 -0
  323. package/dist/sidecar/__tests__/collector.test.js.map +1 -0
  324. package/dist/sidecar/__tests__/render.test.d.ts +2 -0
  325. package/dist/sidecar/__tests__/render.test.d.ts.map +1 -0
  326. package/dist/sidecar/__tests__/render.test.js +67 -0
  327. package/dist/sidecar/__tests__/render.test.js.map +1 -0
  328. package/dist/sidecar/__tests__/tmux.test.d.ts +2 -0
  329. package/dist/sidecar/__tests__/tmux.test.d.ts.map +1 -0
  330. package/dist/sidecar/__tests__/tmux.test.js +30 -0
  331. package/dist/sidecar/__tests__/tmux.test.js.map +1 -0
  332. package/dist/sidecar/__tests__/watch.test.d.ts +2 -0
  333. package/dist/sidecar/__tests__/watch.test.d.ts.map +1 -0
  334. package/dist/sidecar/__tests__/watch.test.js +42 -0
  335. package/dist/sidecar/__tests__/watch.test.js.map +1 -0
  336. package/dist/sidecar/collector.d.ts +4 -0
  337. package/dist/sidecar/collector.d.ts.map +1 -0
  338. package/dist/sidecar/collector.js +377 -0
  339. package/dist/sidecar/collector.js.map +1 -0
  340. package/dist/sidecar/index.d.ts +25 -0
  341. package/dist/sidecar/index.d.ts.map +1 -0
  342. package/dist/sidecar/index.js +165 -0
  343. package/dist/sidecar/index.js.map +1 -0
  344. package/dist/sidecar/render.d.ts +3 -0
  345. package/dist/sidecar/render.d.ts.map +1 -0
  346. package/dist/sidecar/render.js +72 -0
  347. package/dist/sidecar/render.js.map +1 -0
  348. package/dist/sidecar/tmux.d.ts +13 -0
  349. package/dist/sidecar/tmux.d.ts.map +1 -0
  350. package/dist/sidecar/tmux.js +44 -0
  351. package/dist/sidecar/tmux.js.map +1 -0
  352. package/dist/sidecar/types.d.ts +125 -0
  353. package/dist/sidecar/types.d.ts.map +1 -0
  354. package/dist/sidecar/types.js +2 -0
  355. package/dist/sidecar/types.js.map +1 -0
  356. package/dist/state/__tests__/operations.test.js +50 -22
  357. package/dist/state/__tests__/operations.test.js.map +1 -1
  358. package/dist/state/__tests__/workflow-transition.test.js +9 -1
  359. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  360. package/dist/state/operations.d.ts +1 -1
  361. package/dist/state/operations.d.ts.map +1 -1
  362. package/dist/state/operations.js +19 -7
  363. package/dist/state/operations.js.map +1 -1
  364. package/dist/state/workflow-transition.d.ts.map +1 -1
  365. package/dist/state/workflow-transition.js +1 -0
  366. package/dist/state/workflow-transition.js.map +1 -1
  367. package/dist/team/__tests__/commit-hygiene.test.d.ts +2 -0
  368. package/dist/team/__tests__/commit-hygiene.test.d.ts.map +1 -0
  369. package/dist/team/__tests__/commit-hygiene.test.js +93 -0
  370. package/dist/team/__tests__/commit-hygiene.test.js.map +1 -0
  371. package/dist/team/__tests__/delegation-policy.test.d.ts +2 -0
  372. package/dist/team/__tests__/delegation-policy.test.d.ts.map +1 -0
  373. package/dist/team/__tests__/delegation-policy.test.js +69 -0
  374. package/dist/team/__tests__/delegation-policy.test.js.map +1 -0
  375. package/dist/team/__tests__/events.test.js +54 -4
  376. package/dist/team/__tests__/events.test.js.map +1 -1
  377. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +2 -0
  378. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +1 -0
  379. package/dist/team/__tests__/hook-primary-e2e-contract.test.js +78 -0
  380. package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +1 -0
  381. package/dist/team/__tests__/model-contract.test.js +16 -0
  382. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  383. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +2 -0
  384. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +1 -0
  385. package/dist/team/__tests__/repo-aware-decomposition.test.js +95 -0
  386. package/dist/team/__tests__/repo-aware-decomposition.test.js.map +1 -0
  387. package/dist/team/__tests__/runtime.test.js +623 -14
  388. package/dist/team/__tests__/runtime.test.js.map +1 -1
  389. package/dist/team/__tests__/state-root.test.js +177 -1
  390. package/dist/team/__tests__/state-root.test.js.map +1 -1
  391. package/dist/team/__tests__/state.test.js +110 -0
  392. package/dist/team/__tests__/state.test.js.map +1 -1
  393. package/dist/team/__tests__/tmux-session.test.js +399 -2
  394. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  395. package/dist/team/__tests__/worker-bootstrap.test.js +94 -0
  396. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  397. package/dist/team/commit-hygiene.d.ts +22 -3
  398. package/dist/team/commit-hygiene.d.ts.map +1 -1
  399. package/dist/team/commit-hygiene.js +134 -2
  400. package/dist/team/commit-hygiene.js.map +1 -1
  401. package/dist/team/contracts.d.ts +1 -1
  402. package/dist/team/contracts.d.ts.map +1 -1
  403. package/dist/team/contracts.js +2 -0
  404. package/dist/team/contracts.js.map +1 -1
  405. package/dist/team/dag-schema.d.ts +38 -0
  406. package/dist/team/dag-schema.d.ts.map +1 -0
  407. package/dist/team/dag-schema.js +221 -0
  408. package/dist/team/dag-schema.js.map +1 -0
  409. package/dist/team/delegation-policy.d.ts +3 -0
  410. package/dist/team/delegation-policy.d.ts.map +1 -0
  411. package/dist/team/delegation-policy.js +82 -0
  412. package/dist/team/delegation-policy.js.map +1 -0
  413. package/dist/team/model-contract.d.ts +3 -1
  414. package/dist/team/model-contract.d.ts.map +1 -1
  415. package/dist/team/model-contract.js +44 -5
  416. package/dist/team/model-contract.js.map +1 -1
  417. package/dist/team/repo-aware-decomposition.d.ts +60 -0
  418. package/dist/team/repo-aware-decomposition.d.ts.map +1 -0
  419. package/dist/team/repo-aware-decomposition.js +229 -0
  420. package/dist/team/repo-aware-decomposition.js.map +1 -0
  421. package/dist/team/runtime.d.ts +27 -0
  422. package/dist/team/runtime.d.ts.map +1 -1
  423. package/dist/team/runtime.js +172 -52
  424. package/dist/team/runtime.js.map +1 -1
  425. package/dist/team/state/tasks.d.ts.map +1 -1
  426. package/dist/team/state/tasks.js +33 -0
  427. package/dist/team/state/tasks.js.map +1 -1
  428. package/dist/team/state/types.d.ts +23 -1
  429. package/dist/team/state/types.d.ts.map +1 -1
  430. package/dist/team/state/types.js.map +1 -1
  431. package/dist/team/state-root.d.ts +35 -0
  432. package/dist/team/state-root.d.ts.map +1 -1
  433. package/dist/team/state-root.js +281 -1
  434. package/dist/team/state-root.js.map +1 -1
  435. package/dist/team/state.d.ts +27 -1
  436. package/dist/team/state.d.ts.map +1 -1
  437. package/dist/team/state.js +6 -0
  438. package/dist/team/state.js.map +1 -1
  439. package/dist/team/tmux-session.d.ts +1 -0
  440. package/dist/team/tmux-session.d.ts.map +1 -1
  441. package/dist/team/tmux-session.js +105 -6
  442. package/dist/team/tmux-session.js.map +1 -1
  443. package/dist/team/worker-bootstrap.d.ts +3 -0
  444. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  445. package/dist/team/worker-bootstrap.js +77 -4
  446. package/dist/team/worker-bootstrap.js.map +1 -1
  447. package/dist/utils/agents-md.d.ts +3 -0
  448. package/dist/utils/agents-md.d.ts.map +1 -1
  449. package/dist/utils/agents-md.js +25 -0
  450. package/dist/utils/agents-md.js.map +1 -1
  451. package/package.json +3 -2
  452. package/plugins/oh-my-codex/.codex-plugin/plugin.json +2 -2
  453. package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +1 -1
  454. package/plugins/oh-my-codex/skills/analyze/SKILL.md +1 -1
  455. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +134 -205
  456. package/plugins/oh-my-codex/skills/code-review/SKILL.md +4 -4
  457. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +14 -7
  458. package/plugins/oh-my-codex/skills/doctor/SKILL.md +1 -1
  459. package/plugins/oh-my-codex/skills/help/SKILL.md +1 -1
  460. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +41 -10
  461. package/plugins/oh-my-codex/skills/plan/SKILL.md +12 -14
  462. package/plugins/oh-my-codex/skills/ralph/SKILL.md +2 -4
  463. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +5 -9
  464. package/plugins/oh-my-codex/skills/security-review/SKILL.md +4 -4
  465. package/plugins/oh-my-codex/skills/team/SKILL.md +2 -5
  466. package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +2 -5
  467. package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +2 -3
  468. package/prompts/analyst.md +2 -2
  469. package/prompts/api-reviewer.md +2 -2
  470. package/prompts/architect.md +2 -2
  471. package/prompts/build-fixer.md +2 -2
  472. package/prompts/code-reviewer.md +15 -5
  473. package/prompts/code-simplifier.md +1 -1
  474. package/prompts/critic.md +35 -83
  475. package/prompts/debugger.md +2 -2
  476. package/prompts/dependency-expert.md +2 -2
  477. package/prompts/designer.md +2 -2
  478. package/prompts/executor.md +40 -114
  479. package/prompts/explore-harness.md +1 -1
  480. package/prompts/explore.md +37 -90
  481. package/prompts/git-master.md +2 -2
  482. package/prompts/information-architect.md +1 -1
  483. package/prompts/performance-reviewer.md +2 -2
  484. package/prompts/planner.md +35 -62
  485. package/prompts/product-analyst.md +2 -2
  486. package/prompts/product-manager.md +2 -2
  487. package/prompts/qa-tester.md +2 -2
  488. package/prompts/quality-reviewer.md +2 -2
  489. package/prompts/quality-strategist.md +2 -2
  490. package/prompts/researcher.md +46 -78
  491. package/prompts/security-reviewer.md +2 -2
  492. package/prompts/sisyphus-lite.md +2 -2
  493. package/prompts/style-reviewer.md +2 -2
  494. package/prompts/team-executor.md +1 -1
  495. package/prompts/test-engineer.md +2 -2
  496. package/prompts/ux-researcher.md +2 -2
  497. package/prompts/verifier.md +29 -34
  498. package/prompts/vision.md +2 -2
  499. package/prompts/writer.md +2 -2
  500. package/skills/ai-slop-cleaner/SKILL.md +1 -1
  501. package/skills/analyze/SKILL.md +1 -1
  502. package/skills/autopilot/SKILL.md +134 -205
  503. package/skills/build-fix/SKILL.md +4 -4
  504. package/skills/code-review/SKILL.md +4 -4
  505. package/skills/deep-interview/SKILL.md +14 -7
  506. package/skills/doctor/SKILL.md +1 -1
  507. package/skills/help/SKILL.md +1 -1
  508. package/skills/omx-setup/SKILL.md +41 -10
  509. package/skills/plan/SKILL.md +12 -14
  510. package/skills/ralph/SKILL.md +2 -4
  511. package/skills/ralplan/SKILL.md +5 -9
  512. package/skills/security-review/SKILL.md +4 -4
  513. package/skills/team/SKILL.md +2 -5
  514. package/skills/ultraqa/SKILL.md +2 -5
  515. package/skills/ultrawork/SKILL.md +2 -3
  516. package/src/scripts/__tests__/codex-native-hook.test.ts +502 -94
  517. package/src/scripts/__tests__/generate-release-body.test.ts +41 -0
  518. package/src/scripts/__tests__/prompt-inventory.test.ts +64 -0
  519. package/src/scripts/codex-native-hook.ts +293 -61
  520. package/src/scripts/codex-native-pre-post.ts +10 -8
  521. package/src/scripts/generate-release-body.ts +13 -2
  522. package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +180 -0
  523. package/src/scripts/notify-hook/managed-tmux.ts +196 -9
  524. package/src/scripts/notify-hook/process-runner.ts +7 -3
  525. package/src/scripts/notify-hook/team-dispatch.ts +103 -11
  526. package/src/scripts/notify-hook/team-tmux-guard.ts +3 -3
  527. package/src/scripts/notify-hook/team-worker-posttooluse.ts +536 -0
  528. package/src/scripts/notify-hook/team-worker.ts +4 -48
  529. package/src/scripts/notify-hook/tmux-injection.ts +24 -6
  530. package/src/scripts/notify-hook.ts +36 -5
  531. package/src/scripts/prompt-inventory.ts +218 -0
  532. package/src/scripts/run-test-files.ts +1 -0
  533. package/templates/AGENTS.md +34 -95
package/dist/cli/index.js CHANGED
@@ -12,6 +12,7 @@ import { version } from "./version.js";
12
12
  import { tmuxHookCommand } from "./tmux-hook.js";
13
13
  import { hooksCommand } from "./hooks.js";
14
14
  import { hudCommand } from "../hud/index.js";
15
+ import { sidecarCommand } from "../sidecar/index.js";
15
16
  import { teamCommand } from "./team.js";
16
17
  import { ralphCommand } from "./ralph.js";
17
18
  import { askCommand } from "./ask.js";
@@ -30,8 +31,8 @@ import { adaptCommand } from "./adapt.js";
30
31
  import { listCommand } from "./list.js";
31
32
  import { MADMAX_FLAG, CODEX_BYPASS_FLAG, HIGH_REASONING_FLAG, XHIGH_REASONING_FLAG, SPARK_FLAG, MADMAX_SPARK_FLAG, CONFIG_FLAG, LONG_CONFIG_FLAG, } from "./constants.js";
32
33
  import { getBaseStateDir, getStateDir, listModeStateFilesWithScopePreference, } from "../mcp/state-paths.js";
33
- import { resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, } from "./codex-home.js";
34
- export { readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, } from "./codex-home.js";
34
+ import { resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
35
+ export { readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
35
36
  import { SKILL_ACTIVE_STATE_MODE, syncCanonicalSkillStateForMode } from "../state/skill-active.js";
36
37
  import { isTrackedWorkflowMode } from "../state/workflow-transition.js";
37
38
  import { maybeCheckAndPromptUpdate, runImmediateUpdate } from "./update.js";
@@ -41,7 +42,7 @@ import { readSessionState, writeSessionStart, writeSessionEnd, resetSessionMetri
41
42
  import { buildClientAttachedReconcileHookName, buildReconcileHudResizeArgs, buildRegisterClientAttachedReconcileArgs, buildRegisterResizeHookArgs, buildResizeHookName, buildResizeHookTarget, buildScheduleDelayedHudResizeArgs, buildUnregisterClientAttachedReconcileArgs, buildUnregisterResizeHookArgs, enableMouseScrolling, isMsysOrGitBash, isNativeWindows, isTmuxAvailable, mitigateCopyModeUnderlineArtifacts, } from "../team/tmux-session.js";
42
43
  import { getPackageRoot } from "../utils/package.js";
43
44
  import { codexConfigPath, rememberOmxLaunchContext, resolveOmxEntryPath } from "../utils/paths.js";
44
- import { repairConfigIfNeeded } from "../config/generator.js";
45
+ import { cleanCodexModelAvailabilityNuxIfNeeded, repairConfigIfNeeded } from "../config/generator.js";
45
46
  import { HUD_TMUX_HEIGHT_LINES } from "../hud/constants.js";
46
47
  import { createHudWatchPane as createSharedHudWatchPane, killTmuxPane as killSharedTmuxPane, listCurrentWindowHudPaneIds, parsePaneIdFromTmuxOutput, } from "../hud/tmux.js";
47
48
  export { parseTmuxPaneSnapshot, isHudWatchPane, findHudWatchPaneIds } from "../hud/tmux.js";
@@ -53,6 +54,7 @@ import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsSha
53
54
  import { parseWorktreeMode, planWorktreeTarget, ensureWorktree, } from "../team/worktree.js";
54
55
  import { ensureReusableNodeModules } from "../utils/repo-deps.js";
55
56
  import { OMX_NOTIFY_TEMP_CONTRACT_ENV, parseNotifyTempContractFromArgs, serializeNotifyTempContract, } from "../notifications/temp-contract.js";
57
+ import { execInjectCommand } from "../exec/followup.js";
56
58
  export function resolveNotifyFallbackWatcherScript(pkgRoot = getPackageRoot()) {
57
59
  return resolveDistScript(pkgRoot, "notify-fallback-watcher.js");
58
60
  }
@@ -69,8 +71,10 @@ export const HELP = `
69
71
  oh-my-codex (omx) - Multi-agent orchestration for Codex CLI
70
72
 
71
73
  Usage:
72
- omx Launch Codex CLI (HUD auto-attaches only when already inside tmux)
74
+ omx Launch Codex CLI (detached tmux by default on supported interactive terminals)
73
75
  omx exec Run codex exec non-interactively with OMX AGENTS/overlay injection
76
+ omx exec inject <session-id> --prompt <text>
77
+ Queue audited follow-up instructions for a running non-interactive exec job
74
78
  omx setup Install skills, prompts, MCP servers, and scope-specific AGENTS.md
75
79
  (user scope prompts for legacy vs plugin skill delivery when needed)
76
80
  omx update Check npm now, update the global install immediately, then refresh setup
@@ -97,6 +101,7 @@ Usage:
97
101
  omx tmux-hook Manage tmux prompt injection workaround (init|status|validate|test)
98
102
  omx hooks Manage hook plugins (init|status|validate|test)
99
103
  omx hud Show HUD statusline (--watch, --json, --preset=NAME)
104
+ omx sidecar Show read-only team/multi-agent visualization (--watch, --json, --tmux)
100
105
  omx state Read/write/list OMX mode state via CLI parity surface
101
106
  omx notepad CLI parity for OMX notepad MCP tools
102
107
  omx project-memory
@@ -128,6 +133,7 @@ Options:
128
133
  --madmax-spark spark model for workers + bypass approvals for leader and workers
129
134
  (shorthand for: --spark --madmax)
130
135
  --notify-temp Enable temporary notification routing for this run/session only
136
+ --direct Launch the interactive leader directly without OMX tmux/HUD management
131
137
  --tmux Launch the interactive leader session in detached tmux
132
138
  --discord Select Discord provider for temporary notification mode
133
139
  --slack Select Slack provider for temporary notification mode
@@ -137,13 +143,32 @@ Options:
137
143
  -w, --worktree[=<name>]
138
144
  Launch Codex in a git worktree (detached when no name is given)
139
145
  --force Force reinstall (overwrite existing files)
146
+ --merge-agents
147
+ Merge OMX-managed AGENTS.md sections into an existing AGENTS.md
148
+ instead of overwriting user-authored content
140
149
  --dry-run Show what would be done without doing it
141
150
  --plugin Use Codex plugin delivery for omx setup and remove legacy OMX-managed user/project components
151
+ --legacy Use legacy setup delivery for omx setup, overriding persisted plugin mode
152
+ --install-mode <legacy|plugin>
153
+ Explicit setup install mode (canonical form; --legacy/--plugin are aliases)
142
154
  --keep-config Skip config.toml cleanup during uninstall
143
155
  --purge Remove .omx/ cache directory during uninstall
144
156
  --verbose Show detailed output
145
157
  --scope Setup scope for "omx setup" only:
146
158
  user | project
159
+
160
+ Launch policy:
161
+ OMX_LAUNCH_POLICY=direct|tmux|detached-tmux|auto
162
+ Choose the default leader launch policy when no CLI policy flag is present
163
+ unset OMX_LAUNCH_POLICY
164
+ Return to the auto/default policy (detached tmux on supported interactive terminals)
165
+ omx --direct --yolo
166
+ Run this launch without OMX tmux/HUD management
167
+ OMX_LAUNCH_POLICY=direct omx --yolo
168
+ Use direct launch from the environment
169
+ OMX_LAUNCH_POLICY=direct omx --tmux --yolo
170
+ CLI policy flags override the environment for one launch
171
+ Config files are intentionally not used for launch policy in this release.
147
172
  `;
148
173
  const REASONING_KEY = "model_reasoning_effort";
149
174
  const MODEL_INSTRUCTIONS_FILE_KEY = "model_instructions_file";
@@ -151,6 +176,7 @@ const TEAM_WORKER_LAUNCH_ARGS_ENV = "OMX_TEAM_WORKER_LAUNCH_ARGS";
151
176
  const TEAM_INHERIT_LEADER_FLAGS_ENV = "OMX_TEAM_INHERIT_LEADER_FLAGS";
152
177
  const OMX_BYPASS_DEFAULT_SYSTEM_PROMPT_ENV = "OMX_BYPASS_DEFAULT_SYSTEM_PROMPT";
153
178
  const OMX_MODEL_INSTRUCTIONS_FILE_ENV = "OMX_MODEL_INSTRUCTIONS_FILE";
179
+ const OMX_INSTANCE_OPTION = "@omx_instance_id";
154
180
  const OMX_RALPH_APPEND_INSTRUCTIONS_FILE_ENV = "OMX_RALPH_APPEND_INSTRUCTIONS_FILE";
155
181
  const OMX_AUTORESEARCH_APPEND_INSTRUCTIONS_FILE_ENV = "OMX_AUTORESEARCH_APPEND_INSTRUCTIONS_FILE";
156
182
  const REASONING_MODES = ["low", "medium", "high", "xhigh"];
@@ -170,6 +196,7 @@ const ALLOWED_SHELLS = new Set([
170
196
  "/usr/local/bin/bash",
171
197
  "/usr/local/bin/zsh",
172
198
  "/usr/local/bin/fish",
199
+ "/opt/local/bin/zsh",
173
200
  "/opt/homebrew/bin/zsh",
174
201
  ]);
175
202
  const WINDOWS_DETACHED_BOOTSTRAP_DELAY_MS = 2500;
@@ -193,6 +220,7 @@ const NESTED_HELP_COMMANDS = new Set([
193
220
  "hooks",
194
221
  "list",
195
222
  "hud",
223
+ "sidecar",
196
224
  "state",
197
225
  "wiki",
198
226
  "mcp-serve",
@@ -204,9 +232,44 @@ const NESTED_HELP_COMMANDS = new Set([
204
232
  "tmux-hook",
205
233
  ]);
206
234
  export function resolveSetupInstallModeArg(args) {
207
- if (args.includes("--plugin"))
208
- return "plugin";
209
- return undefined;
235
+ let value;
236
+ const setValue = (next, source) => {
237
+ if (value && value !== next) {
238
+ throw new Error(`Conflicting setup install mode flags: ${source} selects ${next}, but another flag already selected ${value}`);
239
+ }
240
+ value = next;
241
+ };
242
+ for (let index = 0; index < args.length; index += 1) {
243
+ const arg = args[index];
244
+ if (arg === "--plugin") {
245
+ setValue("plugin", arg);
246
+ continue;
247
+ }
248
+ if (arg === "--legacy") {
249
+ setValue("legacy", arg);
250
+ continue;
251
+ }
252
+ if (arg === "--install-mode") {
253
+ const next = args[index + 1];
254
+ if (!next || next.startsWith("-")) {
255
+ throw new Error(`Missing setup install mode value after --install-mode. Expected one of: legacy, plugin`);
256
+ }
257
+ if (next !== "legacy" && next !== "plugin") {
258
+ throw new Error(`Invalid setup install mode: ${next}. Expected one of: legacy, plugin`);
259
+ }
260
+ setValue(next, arg);
261
+ index += 1;
262
+ continue;
263
+ }
264
+ if (arg.startsWith("--install-mode=")) {
265
+ const next = arg.slice("--install-mode=".length);
266
+ if (next !== "legacy" && next !== "plugin") {
267
+ throw new Error(`Invalid setup install mode: ${next}. Expected one of: legacy, plugin`);
268
+ }
269
+ setValue(next, "--install-mode");
270
+ }
271
+ }
272
+ return value;
210
273
  }
211
274
  export function resolveSetupScopeArg(args) {
212
275
  let value;
@@ -260,6 +323,8 @@ export function resolveNotifyTempContract(args, env = process.env) {
260
323
  export function commandOwnsLocalHelp(command) {
261
324
  return NESTED_HELP_COMMANDS.has(command);
262
325
  }
326
+ const OMX_LAUNCH_POLICY_ENV = "OMX_LAUNCH_POLICY";
327
+ let warnedInvalidEnvLaunchPolicy = false;
263
328
  function splitLeaderLaunchPolicyArgs(args) {
264
329
  const remainingArgs = [];
265
330
  let explicitPolicy;
@@ -274,6 +339,10 @@ function splitLeaderLaunchPolicyArgs(args) {
274
339
  remainingArgs.push(arg);
275
340
  continue;
276
341
  }
342
+ if (arg === "--direct") {
343
+ explicitPolicy = "direct";
344
+ continue;
345
+ }
277
346
  if (arg === "--tmux") {
278
347
  explicitPolicy = "detached-tmux";
279
348
  continue;
@@ -285,13 +354,34 @@ function splitLeaderLaunchPolicyArgs(args) {
285
354
  export function resolveLeaderLaunchPolicyOverride(args) {
286
355
  return splitLeaderLaunchPolicyArgs(args).explicitPolicy;
287
356
  }
357
+ export function resolveEnvLaunchPolicyOverride(env = process.env) {
358
+ const rawValue = env[OMX_LAUNCH_POLICY_ENV]?.trim();
359
+ if (!rawValue)
360
+ return undefined;
361
+ const value = rawValue.toLowerCase();
362
+ if (value === "auto")
363
+ return undefined;
364
+ if (value === "direct")
365
+ return "direct";
366
+ if (value === "tmux" || value === "detached-tmux")
367
+ return "detached-tmux";
368
+ if (!warnedInvalidEnvLaunchPolicy) {
369
+ warnedInvalidEnvLaunchPolicy = true;
370
+ console.warn(`[omx] warning: invalid ${OMX_LAUNCH_POLICY_ENV}="${rawValue}". ` +
371
+ "Expected direct, tmux, detached-tmux, or auto. Falling back to auto/default launch policy.");
372
+ }
373
+ return undefined;
374
+ }
375
+ export function resolveEffectiveLeaderLaunchPolicyOverride(args, env = process.env) {
376
+ return (resolveLeaderLaunchPolicyOverride(args) ?? resolveEnvLaunchPolicyOverride(env));
377
+ }
288
378
  export function resolveCodexLaunchPolicy(env = process.env, _platform = process.platform, tmuxAvailable = isTmuxAvailable(), nativeWindows = isNativeWindows(), stdinIsTTY = Boolean(process.stdin.isTTY), stdoutIsTTY = Boolean(process.stdout.isTTY), explicitPolicy) {
379
+ if (explicitPolicy === "direct")
380
+ return "direct";
289
381
  if (env.TMUX)
290
382
  return "inside-tmux";
291
383
  if (explicitPolicy === "detached-tmux")
292
384
  return tmuxAvailable ? "detached-tmux" : "direct";
293
- if (explicitPolicy === "direct")
294
- return "direct";
295
385
  if (_platform === "win32")
296
386
  return "direct";
297
387
  if (nativeWindows)
@@ -334,7 +424,8 @@ function tmuxFailureMessage(error) {
334
424
  return detail.replace(/\s+/g, " ");
335
425
  }
336
426
  function isBenignMissingTmuxServerMessage(message) {
337
- return /no server running/i.test(message);
427
+ return (/no server running/i.test(message) ||
428
+ /error connecting to .*\(No such file or directory\)/i.test(message));
338
429
  }
339
430
  export function checkDetachedTmuxLaunchHealth() {
340
431
  try {
@@ -476,6 +567,7 @@ export async function main(args) {
476
567
  "tmux-hook",
477
568
  "hooks",
478
569
  "hud",
570
+ "sidecar",
479
571
  "state",
480
572
  "mcp-serve",
481
573
  "status",
@@ -489,6 +581,7 @@ export async function main(args) {
489
581
  const flags = new Set(args.filter((a) => a.startsWith("--")));
490
582
  const options = {
491
583
  force: flags.has("--force"),
584
+ mergeAgents: flags.has("--merge-agents"),
492
585
  dryRun: flags.has("--dry-run"),
493
586
  verbose: flags.has("--verbose"),
494
587
  team: flags.has("--team"),
@@ -508,6 +601,7 @@ export async function main(args) {
508
601
  case "setup":
509
602
  await setup({
510
603
  force: options.force,
604
+ mergeAgents: options.mergeAgents,
511
605
  dryRun: options.dryRun,
512
606
  verbose: options.verbose,
513
607
  scope: resolveSetupScopeArg(args.slice(1)),
@@ -562,7 +656,12 @@ export async function main(args) {
562
656
  await exploreCommand(args.slice(1));
563
657
  break;
564
658
  case "exec":
565
- await execWithOverlay(launchArgs);
659
+ if (launchArgs[0] === "inject") {
660
+ await execInjectCommand(launchArgs);
661
+ }
662
+ else {
663
+ await execWithOverlay(launchArgs);
664
+ }
566
665
  break;
567
666
  case "sparkshell":
568
667
  await sparkshellCommand(args.slice(1));
@@ -582,6 +681,9 @@ export async function main(args) {
582
681
  case "hud":
583
682
  await hudCommand(args.slice(1));
584
683
  break;
684
+ case "sidecar":
685
+ await sidecarCommand(args.slice(1));
686
+ break;
585
687
  case "state":
586
688
  await stateCommand(args.slice(1));
587
689
  break;
@@ -729,8 +831,9 @@ export async function launchWithHud(args) {
729
831
  const launchCwd = process.cwd();
730
832
  const parsedWorktree = parseWorktreeMode(args);
731
833
  const notifyTempResult = resolveNotifyTempContract(parsedWorktree.remainingArgs, process.env);
732
- const explicitLaunchPolicy = resolveLeaderLaunchPolicyOverride(notifyTempResult.passthroughArgs);
834
+ const explicitLaunchPolicy = resolveEffectiveLeaderLaunchPolicyOverride(notifyTempResult.passthroughArgs, process.env);
733
835
  const codexHomeOverride = resolveCodexHomeForLaunch(launchCwd, process.env);
836
+ const projectLocalCodexHomeForCleanup = resolveProjectLocalCodexHomeForLaunch(launchCwd, process.env);
734
837
  const { launchPolicy, effectiveExplicitLaunchPolicy } = resolveTmuxAwareLaunchPolicy(explicitLaunchPolicy, isNativeWindows());
735
838
  const enableNotifyFallbackAuthority = launchPolicy === "direct";
736
839
  const workerSparkModel = resolveWorkerSparkModel(notifyTempResult.passthroughArgs, codexHomeOverride);
@@ -805,7 +908,7 @@ export async function launchWithHud(args) {
805
908
  }
806
909
  finally {
807
910
  // ── Phase 3: postLaunch ─────────────────────────────────────────────
808
- await postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbackAuthority);
911
+ await postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbackAuthority, projectLocalCodexHomeForCleanup);
809
912
  }
810
913
  }
811
914
  export async function execWithOverlay(args) {
@@ -813,6 +916,7 @@ export async function execWithOverlay(args) {
813
916
  const parsedWorktree = parseWorktreeMode(args);
814
917
  const notifyTempResult = resolveNotifyTempContract(parsedWorktree.remainingArgs, process.env);
815
918
  const codexHomeOverride = resolveCodexHomeForLaunch(launchCwd, process.env);
919
+ const projectLocalCodexHomeForCleanup = resolveProjectLocalCodexHomeForLaunch(launchCwd, process.env);
816
920
  const normalizedArgs = normalizeCodexLaunchArgs(notifyTempResult.passthroughArgs);
817
921
  let cwd = launchCwd;
818
922
  let worktreeDirty = false;
@@ -884,7 +988,7 @@ export async function execWithOverlay(args) {
884
988
  runCodexBlocking(cwd, codexArgs, codexEnv);
885
989
  }
886
990
  finally {
887
- await postLaunch(cwd, sessionId, codexHomeOverride, true);
991
+ await postLaunch(cwd, sessionId, codexHomeOverride, true, projectLocalCodexHomeForCleanup);
888
992
  }
889
993
  }
890
994
  export function normalizeCodexLaunchArgs(args) {
@@ -1020,6 +1124,36 @@ export function resolveNativeSessionName(cwd, sessionId, env = process.env) {
1020
1124
  }
1021
1125
  return buildTmuxSessionName(cwd, sessionId);
1022
1126
  }
1127
+ function tagTmuxSessionWithInstance(sessionName, sessionId) {
1128
+ const target = sessionName.trim();
1129
+ const instanceId = sessionId.trim();
1130
+ if (!target || !instanceId)
1131
+ return;
1132
+ execFileSync("tmux", ["set-option", "-t", target, OMX_INSTANCE_OPTION, instanceId], {
1133
+ stdio: ["ignore", "ignore", "ignore"],
1134
+ timeout: 2000,
1135
+ });
1136
+ }
1137
+ function tagCurrentTmuxSessionWithInstance(sessionId) {
1138
+ if (!process.env.TMUX)
1139
+ return;
1140
+ try {
1141
+ const tmuxPaneTarget = process.env.TMUX_PANE;
1142
+ const displayArgs = tmuxPaneTarget
1143
+ ? ["display-message", "-p", "-t", tmuxPaneTarget, "#S"]
1144
+ : ["display-message", "-p", "#S"];
1145
+ const sessionName = execFileSync("tmux", displayArgs, {
1146
+ encoding: "utf-8",
1147
+ stdio: ["ignore", "pipe", "ignore"],
1148
+ timeout: 2000,
1149
+ }).trim();
1150
+ if (sessionName)
1151
+ tagTmuxSessionWithInstance(sessionName, sessionId);
1152
+ }
1153
+ catch {
1154
+ // Best effort only: launch should not fail just because tmux tagging failed.
1155
+ }
1156
+ }
1023
1157
  function buildNativeHookBaseContext(cwd, sessionId, normalizedEvent, extra = {}) {
1024
1158
  const repoPath = tryReadGitValue(cwd, ["rev-parse", "--show-toplevel"]) || cwd;
1025
1159
  const branch = tryReadGitValue(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]);
@@ -1215,6 +1349,24 @@ function resolveTmuxSocketPath(execFileSyncImpl = (file, tmuxArgs) => execFileSy
1215
1349
  function tmuxExtendedKeysLeasePath(cwd, socketPath) {
1216
1350
  return join(tmuxExtendedKeysLeaseRoot(cwd), `${sanitizeTmuxLeaseKey(socketPath)}.json`);
1217
1351
  }
1352
+ function isTmuxExtendedKeysLeaseHolderRecord(holder) {
1353
+ if (!holder || typeof holder !== "object")
1354
+ return false;
1355
+ const record = holder;
1356
+ if (typeof record.id !== "string" || !record.id.trim())
1357
+ return false;
1358
+ if (!Number.isSafeInteger(record.pid) || Number(record.pid) <= 0)
1359
+ return false;
1360
+ if (record.platform !== undefined && typeof record.platform !== "string")
1361
+ return false;
1362
+ if (record.linuxStartTicks !== undefined &&
1363
+ !Number.isSafeInteger(record.linuxStartTicks))
1364
+ return false;
1365
+ return true;
1366
+ }
1367
+ function isTmuxExtendedKeysLeaseHolder(holder) {
1368
+ return typeof holder === "string" || isTmuxExtendedKeysLeaseHolderRecord(holder);
1369
+ }
1218
1370
  function readTmuxExtendedKeysLeaseState(leasePath) {
1219
1371
  if (!existsSync(leasePath))
1220
1372
  return null;
@@ -1222,7 +1374,7 @@ function readTmuxExtendedKeysLeaseState(leasePath) {
1222
1374
  const parsed = JSON.parse(readFileSync(leasePath, "utf-8"));
1223
1375
  if (typeof parsed.originalMode !== "string" ||
1224
1376
  !Array.isArray(parsed.holders) ||
1225
- !parsed.holders.every((holder) => typeof holder === "string")) {
1377
+ !parsed.holders.every(isTmuxExtendedKeysLeaseHolder)) {
1226
1378
  return null;
1227
1379
  }
1228
1380
  return {
@@ -1238,6 +1390,81 @@ function writeTmuxExtendedKeysLeaseState(leasePath, state) {
1238
1390
  mkdirSync(dirname(leasePath), { recursive: true });
1239
1391
  writeFileSync(leasePath, JSON.stringify(state, null, 2));
1240
1392
  }
1393
+ function parseTmuxExtendedKeysLeaseHolderPid(holder) {
1394
+ const match = /^([1-9]\d*)-/.exec(holder);
1395
+ if (!match)
1396
+ return null;
1397
+ const pid = Number.parseInt(match[1], 10);
1398
+ return Number.isSafeInteger(pid) && pid > 0 ? pid : null;
1399
+ }
1400
+ function getTmuxExtendedKeysLeaseHolderId(holder) {
1401
+ return typeof holder === "string" ? holder : holder.id;
1402
+ }
1403
+ function getTmuxExtendedKeysLeaseHolderPid(holder) {
1404
+ if (typeof holder === "string")
1405
+ return parseTmuxExtendedKeysLeaseHolderPid(holder);
1406
+ return Number.isSafeInteger(holder.pid) && holder.pid > 0 ? holder.pid : null;
1407
+ }
1408
+ function parseLinuxProcStartTicks(statContent) {
1409
+ const commandEnd = statContent.lastIndexOf(")");
1410
+ if (commandEnd === -1)
1411
+ return null;
1412
+ const remainder = statContent.slice(commandEnd + 1).trim();
1413
+ const fields = remainder.split(/\s+/);
1414
+ if (fields.length <= 19)
1415
+ return null;
1416
+ const startTicks = Number(fields[19]);
1417
+ return Number.isSafeInteger(startTicks) ? startTicks : null;
1418
+ }
1419
+ function readLinuxProcessStartTicks(pid) {
1420
+ try {
1421
+ return parseLinuxProcStartTicks(readFileSync(`/proc/${pid}/stat`, "utf-8"));
1422
+ }
1423
+ catch {
1424
+ return null;
1425
+ }
1426
+ }
1427
+ function createTmuxExtendedKeysLeaseHolder(id, pid) {
1428
+ const linuxStartTicks = process.platform === "linux"
1429
+ ? readLinuxProcessStartTicks(pid) ?? undefined
1430
+ : undefined;
1431
+ return {
1432
+ id,
1433
+ pid,
1434
+ platform: process.platform,
1435
+ ...(linuxStartTicks !== undefined ? { linuxStartTicks } : {}),
1436
+ };
1437
+ }
1438
+ function isProcessAlive(pid) {
1439
+ try {
1440
+ process.kill(pid, 0);
1441
+ return true;
1442
+ }
1443
+ catch (err) {
1444
+ const code = err && typeof err === "object" && "code" in err
1445
+ ? String(err.code)
1446
+ : "";
1447
+ return code === "EPERM";
1448
+ }
1449
+ }
1450
+ function isTmuxExtendedKeysLeaseHolderAlive(holder) {
1451
+ const pid = getTmuxExtendedKeysLeaseHolderPid(holder);
1452
+ if (pid === null || !isProcessAlive(pid))
1453
+ return false;
1454
+ if (typeof holder === "string")
1455
+ return true;
1456
+ if (holder.platform !== "linux" || process.platform !== "linux")
1457
+ return true;
1458
+ if (holder.linuxStartTicks === undefined)
1459
+ return true;
1460
+ return readLinuxProcessStartTicks(pid) === holder.linuxStartTicks;
1461
+ }
1462
+ function reapDeadTmuxExtendedKeysLeaseHolders(state) {
1463
+ return {
1464
+ originalMode: state.originalMode,
1465
+ holders: state.holders.filter(isTmuxExtendedKeysLeaseHolderAlive),
1466
+ };
1467
+ }
1241
1468
  function withTmuxExtendedKeysLeaseLock(cwd, socketPath, run) {
1242
1469
  const leaseRoot = tmuxExtendedKeysLeaseRoot(cwd);
1243
1470
  mkdirSync(leaseRoot, { recursive: true });
@@ -1317,24 +1544,30 @@ function execTmuxSync(args, execFileSyncImpl = (file, tmuxArgs) => execFileSync(
1317
1544
  export function acquireTmuxExtendedKeysLease(cwd, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1318
1545
  encoding: "utf-8",
1319
1546
  ...(process.platform === "win32" ? { windowsHide: true } : {}),
1320
- })) {
1547
+ }), ownerPid = process.pid) {
1321
1548
  try {
1322
1549
  const socketPath = resolveTmuxSocketPath(execFileSyncImpl);
1323
1550
  const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
1324
- const leaseId = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1551
+ const holderPid = Number.isSafeInteger(ownerPid) && ownerPid > 0 ? ownerPid : process.pid;
1552
+ const leaseId = `${holderPid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1325
1553
  withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
1326
- const state = readTmuxExtendedKeysLeaseState(leasePath);
1554
+ const stateRaw = readTmuxExtendedKeysLeaseState(leasePath);
1555
+ const state = stateRaw ? reapDeadTmuxExtendedKeysLeaseHolders(stateRaw) : null;
1556
+ if (stateRaw && state?.holders.length === 0) {
1557
+ execTmuxSync(["set-option", "-sq", "extended-keys", state.originalMode], execFileSyncImpl);
1558
+ rmSync(leasePath, { force: true });
1559
+ }
1327
1560
  if (!state || state.holders.length === 0) {
1328
1561
  const previousMode = execTmuxSync(["show-options", "-sv", "extended-keys"], execFileSyncImpl) ||
1329
1562
  TMUX_EXTENDED_KEYS_FALLBACK_MODE;
1330
1563
  execTmuxSync(["set-option", "-sq", "extended-keys", TMUX_EXTENDED_KEYS_MODE], execFileSyncImpl);
1331
1564
  writeTmuxExtendedKeysLeaseState(leasePath, {
1332
1565
  originalMode: previousMode,
1333
- holders: [leaseId],
1566
+ holders: [createTmuxExtendedKeysLeaseHolder(leaseId, holderPid)],
1334
1567
  });
1335
1568
  return;
1336
1569
  }
1337
- state.holders.push(leaseId);
1570
+ state.holders.push(createTmuxExtendedKeysLeaseHolder(leaseId, holderPid));
1338
1571
  writeTmuxExtendedKeysLeaseState(leasePath, state);
1339
1572
  });
1340
1573
  return `${socketPath}\t${leaseId}`;
@@ -1357,12 +1590,16 @@ export function releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl
1357
1590
  try {
1358
1591
  const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
1359
1592
  withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
1360
- const state = readTmuxExtendedKeysLeaseState(leasePath);
1593
+ const stateRaw = readTmuxExtendedKeysLeaseState(leasePath);
1594
+ const state = stateRaw ? reapDeadTmuxExtendedKeysLeaseHolders(stateRaw) : null;
1361
1595
  if (!state || state.holders.length === 0) {
1596
+ if (stateRaw) {
1597
+ execTmuxSync(["set-option", "-sq", "extended-keys", stateRaw.originalMode], execFileSyncImpl);
1598
+ }
1362
1599
  rmSync(leasePath, { force: true });
1363
1600
  return;
1364
1601
  }
1365
- const holders = state.holders.filter((holder) => holder !== leaseId);
1602
+ const holders = state.holders.filter((holder) => getTmuxExtendedKeysLeaseHolderId(holder) !== leaseId);
1366
1603
  if (holders.length > 0) {
1367
1604
  writeTmuxExtendedKeysLeaseState(leasePath, {
1368
1605
  originalMode: state.originalMode,
@@ -1382,12 +1619,12 @@ function buildTmuxExtendedKeysHelperCommand(cwd, operation) {
1382
1619
  const cwdLiteral = JSON.stringify(cwd);
1383
1620
  const moduleUrlLiteral = JSON.stringify(import.meta.url);
1384
1621
  const script = operation === "acquire"
1385
- ? `const mod = await import(${moduleUrlLiteral}); const lease = mod.acquireTmuxExtendedKeysLease(${cwdLiteral}); if (lease) process.stdout.write(lease);`
1622
+ ? `const mod = await import(${moduleUrlLiteral}); const ownerPid = Number.parseInt(process.argv[1] ?? "", 10); const lease = mod.acquireTmuxExtendedKeysLease(${cwdLiteral}, undefined, Number.isSafeInteger(ownerPid) && ownerPid > 0 ? ownerPid : undefined); if (lease) process.stdout.write(lease);`
1386
1623
  : `const mod = await import(${moduleUrlLiteral}); mod.releaseTmuxExtendedKeysLease(${cwdLiteral}, process.argv[1] ?? "");`;
1387
1624
  return `${quoteShellArg(process.execPath)} --input-type=module -e ${quoteShellArg(script)}`;
1388
1625
  }
1389
1626
  function buildTmuxExtendedKeysAcquireShellSnippet(cwd) {
1390
- return `OMX_TMUX_EXTENDED_KEYS_LEASE=$(${buildTmuxExtendedKeysHelperCommand(cwd, "acquire")} 2>/dev/null || true);`;
1627
+ return `OMX_TMUX_EXTENDED_KEYS_LEASE=$(${buildTmuxExtendedKeysHelperCommand(cwd, "acquire")} "$$" 2>/dev/null || true);`;
1391
1628
  }
1392
1629
  function buildTmuxExtendedKeysReleaseShellSnippet(cwd) {
1393
1630
  return `if [ -n "\${OMX_TMUX_EXTENDED_KEYS_LEASE:-}" ]; then ${buildTmuxExtendedKeysHelperCommand(cwd, "release")} "\${OMX_TMUX_EXTENDED_KEYS_LEASE}" >/dev/null 2>&1 || true; fi;`;
@@ -1446,6 +1683,14 @@ export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, h
1446
1683
  ];
1447
1684
  return [
1448
1685
  { name: "new-session", args: newSessionArgs },
1686
+ ...(sessionId
1687
+ ? [
1688
+ {
1689
+ name: "tag-session",
1690
+ args: ["set-option", "-t", sessionName, OMX_INSTANCE_OPTION, sessionId],
1691
+ },
1692
+ ]
1693
+ : []),
1449
1694
  { name: "split-and-capture-hud-pane", args: splitCaptureArgs },
1450
1695
  ];
1451
1696
  }
@@ -1783,6 +2028,7 @@ ${launchAppendix}${dirtyWorktreeGuidance}`
1783
2028
  // 3. Write session state
1784
2029
  await resetSessionMetrics(cwd, sessionId);
1785
2030
  await writeSessionStart(cwd, sessionId);
2031
+ tagCurrentTmuxSessionWithInstance(sessionId);
1786
2032
  // 4. Start notify fallback watcher (best effort)
1787
2033
  try {
1788
2034
  await startNotifyFallbackWatcher(cwd, { codexHomeOverride, enableAuthority: enableNotifyFallbackAuthority, sessionId });
@@ -1943,6 +2189,10 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, n
1943
2189
  ? buildWindowsPromptCommand("codex", launchArgs)
1944
2190
  : null;
1945
2191
  const sessionName = buildDetachedTmuxSessionName(cwd, sessionId);
2192
+ void writeSessionStart(cwd, sessionId, { tmuxSessionName: sessionName }).catch((err) => {
2193
+ logCliOperationFailure(err);
2194
+ // Non-fatal: managed tmux recovery can still use compatibility fallback.
2195
+ });
1946
2196
  let createdDetachedSession = false;
1947
2197
  let registeredHookTarget = null;
1948
2198
  let registeredHookName = null;
@@ -2127,7 +2377,7 @@ function scheduleDetachedWindowsCodexLaunch(sessionName, commandText) {
2127
2377
  * postLaunch: Clean up after Codex exits.
2128
2378
  * Each step is independently fault-tolerant (try/catch per step).
2129
2379
  */
2130
- async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbackAuthority = false) {
2380
+ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbackAuthority = false, projectLocalCodexHomeForCleanup) {
2131
2381
  // Capture session start time before cleanup (writeSessionEnd deletes session.json)
2132
2382
  let sessionStartedAt;
2133
2383
  try {
@@ -2172,6 +2422,15 @@ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbac
2172
2422
  logCliOperationFailure(err);
2173
2423
  // Non-fatal
2174
2424
  }
2425
+ // 0.5. Remove Codex transient TUI NUX counters from project-local config only.
2426
+ try {
2427
+ if (projectLocalCodexHomeForCleanup) {
2428
+ await cleanCodexModelAvailabilityNuxIfNeeded(join(projectLocalCodexHomeForCleanup, "config.toml"));
2429
+ }
2430
+ }
2431
+ catch (err) {
2432
+ console.error(`[omx] postLaunch: project config transient NUX cleanup failed: ${err instanceof Error ? err.message : err}`);
2433
+ }
2175
2434
  // 1. Remove session-scoped model instructions file
2176
2435
  try {
2177
2436
  await removeSessionModelInstructionsFile(cwd, sessionId);