oh-my-codex 0.11.13 → 0.12.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 (377) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +34 -17
  4. package/crates/omx-runtime/src/main.rs +6 -2
  5. package/dist/agents/native-config.js +1 -1
  6. package/dist/agents/native-config.js.map +1 -1
  7. package/dist/cli/__tests__/autoresearch-guided.test.js +74 -2
  8. package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
  9. package/dist/cli/__tests__/cleanup.test.js +37 -30
  10. package/dist/cli/__tests__/cleanup.test.js.map +1 -1
  11. package/dist/cli/__tests__/error-handling-warnings.test.js +3 -1
  12. package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
  13. package/dist/cli/__tests__/index.test.js +276 -5
  14. package/dist/cli/__tests__/index.test.js.map +1 -1
  15. package/dist/cli/__tests__/launch-fallback.test.js +95 -1
  16. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  17. package/dist/cli/__tests__/setup-refresh.test.js +49 -9
  18. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  19. package/dist/cli/__tests__/setup-scope.test.js +9 -0
  20. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  21. package/dist/cli/__tests__/team.test.js +136 -11
  22. package/dist/cli/__tests__/team.test.js.map +1 -1
  23. package/dist/cli/__tests__/uninstall.test.js +10 -0
  24. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  25. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +1 -0
  26. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  27. package/dist/cli/autoresearch-guided.d.ts.map +1 -1
  28. package/dist/cli/autoresearch-guided.js +2 -1
  29. package/dist/cli/autoresearch-guided.js.map +1 -1
  30. package/dist/cli/autoresearch.d.ts.map +1 -1
  31. package/dist/cli/autoresearch.js +2 -1
  32. package/dist/cli/autoresearch.js.map +1 -1
  33. package/dist/cli/cleanup.d.ts.map +1 -1
  34. package/dist/cli/cleanup.js +10 -5
  35. package/dist/cli/cleanup.js.map +1 -1
  36. package/dist/cli/index.d.ts +21 -1
  37. package/dist/cli/index.d.ts.map +1 -1
  38. package/dist/cli/index.js +298 -36
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/omx.js +2 -0
  41. package/dist/cli/omx.js.map +1 -1
  42. package/dist/cli/setup.d.ts +1 -0
  43. package/dist/cli/setup.d.ts.map +1 -1
  44. package/dist/cli/setup.js +41 -7
  45. package/dist/cli/setup.js.map +1 -1
  46. package/dist/cli/team.d.ts.map +1 -1
  47. package/dist/cli/team.js +16 -557
  48. package/dist/cli/team.js.map +1 -1
  49. package/dist/cli/uninstall.d.ts.map +1 -1
  50. package/dist/cli/uninstall.js +34 -9
  51. package/dist/cli/uninstall.js.map +1 -1
  52. package/dist/config/__tests__/generator-idempotent.test.js +79 -2
  53. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  54. package/dist/config/__tests__/generator-notify.test.js +2 -0
  55. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  56. package/dist/config/codex-hooks.d.ts +11 -0
  57. package/dist/config/codex-hooks.d.ts.map +1 -0
  58. package/dist/config/codex-hooks.js +50 -0
  59. package/dist/config/codex-hooks.js.map +1 -0
  60. package/dist/config/generator.d.ts +5 -3
  61. package/dist/config/generator.d.ts.map +1 -1
  62. package/dist/config/generator.js +24 -14
  63. package/dist/config/generator.js.map +1 -1
  64. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +2 -0
  65. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +1 -0
  66. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +20 -0
  67. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +1 -0
  68. package/dist/hooks/__tests__/keyword-detector.test.js +132 -0
  69. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  70. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +292 -4
  71. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  72. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +86 -0
  73. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  74. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +40 -0
  75. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  76. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +2 -0
  77. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +1 -0
  78. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +54 -0
  79. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -0
  80. package/dist/hooks/__tests__/notify-hook-modules.test.js +31 -0
  81. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
  82. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +51 -0
  83. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +2 -0
  85. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +1 -0
  86. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +136 -0
  87. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +1 -0
  88. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +120 -0
  89. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  90. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +145 -20
  91. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  92. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +116 -0
  93. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  94. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +86 -0
  95. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  96. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +1 -0
  97. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
  98. package/dist/hooks/extensibility/__tests__/runtime.test.js +49 -0
  99. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -1
  100. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  101. package/dist/hooks/extensibility/runtime.js +10 -0
  102. package/dist/hooks/extensibility/runtime.js.map +1 -1
  103. package/dist/hooks/extensibility/types.d.ts +1 -1
  104. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  105. package/dist/hooks/keyword-detector.d.ts +2 -0
  106. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  107. package/dist/hooks/keyword-detector.js +76 -4
  108. package/dist/hooks/keyword-detector.js.map +1 -1
  109. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  110. package/dist/hooks/prompt-guidance-contract.js +12 -8
  111. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  112. package/dist/hooks/session.d.ts +5 -1
  113. package/dist/hooks/session.d.ts.map +1 -1
  114. package/dist/hooks/session.js +10 -6
  115. package/dist/hooks/session.js.map +1 -1
  116. package/dist/hud/index.d.ts.map +1 -1
  117. package/dist/hud/index.js +6 -1
  118. package/dist/hud/index.js.map +1 -1
  119. package/dist/mcp/__tests__/bootstrap.test.js +0 -3
  120. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
  121. package/dist/mcp/__tests__/code-intel-server.test.js +27 -1
  122. package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
  123. package/dist/mcp/__tests__/server-lifecycle.test.js +0 -5
  124. package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
  125. package/dist/mcp/bootstrap.d.ts +1 -1
  126. package/dist/mcp/bootstrap.d.ts.map +1 -1
  127. package/dist/mcp/bootstrap.js +0 -1
  128. package/dist/mcp/bootstrap.js.map +1 -1
  129. package/dist/mcp/code-intel-server.d.ts +20 -0
  130. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  131. package/dist/mcp/code-intel-server.js +6 -5
  132. package/dist/mcp/code-intel-server.js.map +1 -1
  133. package/dist/notifications/__tests__/idle-cooldown.test.js +24 -1
  134. package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
  135. package/dist/notifications/__tests__/reply-listener.test.js +20 -1
  136. package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
  137. package/dist/notifications/__tests__/tmux.test.js +41 -0
  138. package/dist/notifications/__tests__/tmux.test.js.map +1 -1
  139. package/dist/notifications/idle-cooldown.d.ts +13 -0
  140. package/dist/notifications/idle-cooldown.d.ts.map +1 -1
  141. package/dist/notifications/idle-cooldown.js +50 -16
  142. package/dist/notifications/idle-cooldown.js.map +1 -1
  143. package/dist/notifications/reply-listener.d.ts.map +1 -1
  144. package/dist/notifications/reply-listener.js +2 -0
  145. package/dist/notifications/reply-listener.js.map +1 -1
  146. package/dist/notifications/tmux.d.ts.map +1 -1
  147. package/dist/notifications/tmux.js +4 -0
  148. package/dist/notifications/tmux.js.map +1 -1
  149. package/dist/scripts/__tests__/codex-native-hook.test.d.ts +2 -0
  150. package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +1 -0
  151. package/dist/scripts/__tests__/codex-native-hook.test.js +1050 -0
  152. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -0
  153. package/dist/scripts/codex-native-hook.d.ts +22 -0
  154. package/dist/scripts/codex-native-hook.d.ts.map +1 -0
  155. package/dist/scripts/codex-native-hook.js +792 -0
  156. package/dist/scripts/codex-native-hook.js.map +1 -0
  157. package/dist/scripts/codex-native-pre-post.d.ts +26 -0
  158. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -0
  159. package/dist/scripts/codex-native-pre-post.js +118 -0
  160. package/dist/scripts/codex-native-pre-post.js.map +1 -0
  161. package/dist/scripts/notify-fallback-watcher.js +322 -21
  162. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  163. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  164. package/dist/scripts/notify-hook/auto-nudge.js +5 -6
  165. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  166. package/dist/scripts/notify-hook/log.d.ts +2 -2
  167. package/dist/scripts/notify-hook/log.d.ts.map +1 -1
  168. package/dist/scripts/notify-hook/log.js +10 -2
  169. package/dist/scripts/notify-hook/log.js.map +1 -1
  170. package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
  171. package/dist/scripts/notify-hook/managed-tmux.js +2 -0
  172. package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
  173. package/dist/scripts/notify-hook/orchestration-intent.d.ts +18 -0
  174. package/dist/scripts/notify-hook/orchestration-intent.d.ts.map +1 -0
  175. package/dist/scripts/notify-hook/orchestration-intent.js +72 -0
  176. package/dist/scripts/notify-hook/orchestration-intent.js.map +1 -0
  177. package/dist/scripts/notify-hook/process-runner.js.map +1 -1
  178. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
  179. package/dist/scripts/notify-hook/ralph-session-resume.js +7 -0
  180. package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
  181. package/dist/scripts/notify-hook/team-dispatch.d.ts +15 -6
  182. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  183. package/dist/scripts/notify-hook/team-dispatch.js +125 -6
  184. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  185. package/dist/scripts/notify-hook/team-leader-nudge.d.ts +3 -2
  186. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  187. package/dist/scripts/notify-hook/team-leader-nudge.js +165 -37
  188. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  189. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +4 -1
  190. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  191. package/dist/scripts/notify-hook/team-tmux-guard.js +33 -44
  192. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  193. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  194. package/dist/scripts/notify-hook/team-worker.js +68 -5
  195. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  196. package/dist/scripts/notify-hook/utils.d.ts +1 -1
  197. package/dist/scripts/notify-hook/utils.d.ts.map +1 -1
  198. package/dist/scripts/notify-hook/utils.js.map +1 -1
  199. package/dist/scripts/notify-hook.js +55 -32
  200. package/dist/scripts/notify-hook.js.map +1 -1
  201. package/dist/team/__tests__/api-interop.test.js +344 -18
  202. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  203. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +2 -0
  204. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +1 -0
  205. package/dist/team/__tests__/delivery-e2e-smoke.test.js +671 -0
  206. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -0
  207. package/dist/team/__tests__/mcp-comm.test.js +5 -0
  208. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  209. package/dist/team/__tests__/runtime.test.js +543 -15
  210. package/dist/team/__tests__/runtime.test.js.map +1 -1
  211. package/dist/team/__tests__/state.test.js +133 -8
  212. package/dist/team/__tests__/state.test.js.map +1 -1
  213. package/dist/team/__tests__/team-ops-contract.test.js +4 -0
  214. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
  215. package/dist/team/__tests__/tmux-session.test.js +160 -0
  216. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  217. package/dist/team/__tests__/worker-bootstrap.test.js +19 -1
  218. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  219. package/dist/team/api-interop.d.ts.map +1 -1
  220. package/dist/team/api-interop.js +95 -23
  221. package/dist/team/api-interop.js.map +1 -1
  222. package/dist/team/contracts.d.ts +11 -1
  223. package/dist/team/contracts.d.ts.map +1 -1
  224. package/dist/team/contracts.js +29 -0
  225. package/dist/team/contracts.js.map +1 -1
  226. package/dist/team/delivery-log.d.ts +14 -0
  227. package/dist/team/delivery-log.d.ts.map +1 -0
  228. package/dist/team/delivery-log.js +35 -0
  229. package/dist/team/delivery-log.js.map +1 -0
  230. package/dist/team/idle-nudge.d.ts +2 -2
  231. package/dist/team/idle-nudge.js +2 -2
  232. package/dist/team/mcp-comm.d.ts +4 -0
  233. package/dist/team/mcp-comm.d.ts.map +1 -1
  234. package/dist/team/mcp-comm.js +84 -1
  235. package/dist/team/mcp-comm.js.map +1 -1
  236. package/dist/team/pane-status.d.ts +149 -0
  237. package/dist/team/pane-status.d.ts.map +1 -0
  238. package/dist/team/pane-status.js +558 -0
  239. package/dist/team/pane-status.js.map +1 -0
  240. package/dist/team/reminder-intents.d.ts +11 -0
  241. package/dist/team/reminder-intents.d.ts.map +1 -0
  242. package/dist/team/reminder-intents.js +40 -0
  243. package/dist/team/reminder-intents.js.map +1 -0
  244. package/dist/team/runtime-cli.d.ts +1 -1
  245. package/dist/team/runtime-cli.js +2 -2
  246. package/dist/team/runtime-cli.js.map +1 -1
  247. package/dist/team/runtime.d.ts +2 -1
  248. package/dist/team/runtime.d.ts.map +1 -1
  249. package/dist/team/runtime.js +409 -191
  250. package/dist/team/runtime.js.map +1 -1
  251. package/dist/team/scaling.d.ts.map +1 -1
  252. package/dist/team/scaling.js +6 -5
  253. package/dist/team/scaling.js.map +1 -1
  254. package/dist/team/state/dispatch.d.ts +4 -1
  255. package/dist/team/state/dispatch.d.ts.map +1 -1
  256. package/dist/team/state/dispatch.js +59 -18
  257. package/dist/team/state/dispatch.js.map +1 -1
  258. package/dist/team/state/mailbox.d.ts.map +1 -1
  259. package/dist/team/state/mailbox.js +45 -2
  260. package/dist/team/state/mailbox.js.map +1 -1
  261. package/dist/team/state/monitor.d.ts +2 -1
  262. package/dist/team/state/monitor.d.ts.map +1 -1
  263. package/dist/team/state/monitor.js +30 -1
  264. package/dist/team/state/monitor.js.map +1 -1
  265. package/dist/team/state/types.d.ts +5 -2
  266. package/dist/team/state/types.d.ts.map +1 -1
  267. package/dist/team/state/types.js.map +1 -1
  268. package/dist/team/state.d.ts +30 -3
  269. package/dist/team/state.d.ts.map +1 -1
  270. package/dist/team/state.js +170 -2
  271. package/dist/team/state.js.map +1 -1
  272. package/dist/team/team-ops.d.ts +5 -1
  273. package/dist/team/team-ops.d.ts.map +1 -1
  274. package/dist/team/team-ops.js +4 -0
  275. package/dist/team/team-ops.js.map +1 -1
  276. package/dist/team/tmux-session.d.ts +2 -0
  277. package/dist/team/tmux-session.d.ts.map +1 -1
  278. package/dist/team/tmux-session.js +19 -3
  279. package/dist/team/tmux-session.js.map +1 -1
  280. package/dist/team/worker-bootstrap.d.ts +4 -0
  281. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  282. package/dist/team/worker-bootstrap.js +33 -6
  283. package/dist/team/worker-bootstrap.js.map +1 -1
  284. package/dist/utils/__tests__/paths.test.js +63 -1
  285. package/dist/utils/__tests__/paths.test.js.map +1 -1
  286. package/dist/utils/__tests__/platform-command.test.js +50 -4
  287. package/dist/utils/__tests__/platform-command.test.js.map +1 -1
  288. package/dist/utils/paths.d.ts +12 -0
  289. package/dist/utils/paths.d.ts.map +1 -1
  290. package/dist/utils/paths.js +44 -2
  291. package/dist/utils/paths.js.map +1 -1
  292. package/dist/utils/platform-command.d.ts.map +1 -1
  293. package/dist/utils/platform-command.js +13 -5
  294. package/dist/utils/platform-command.js.map +1 -1
  295. package/dist/utils/sleep.d.ts.map +1 -1
  296. package/dist/utils/sleep.js +10 -1
  297. package/dist/utils/sleep.js.map +1 -1
  298. package/package.json +1 -1
  299. package/prompts/analyst.md +2 -2
  300. package/prompts/api-reviewer.md +2 -2
  301. package/prompts/architect.md +2 -2
  302. package/prompts/build-fixer.md +2 -2
  303. package/prompts/code-reviewer.md +2 -2
  304. package/prompts/code-simplifier.md +1 -1
  305. package/prompts/critic.md +2 -2
  306. package/prompts/debugger.md +3 -2
  307. package/prompts/dependency-expert.md +2 -2
  308. package/prompts/designer.md +2 -2
  309. package/prompts/executor.md +3 -2
  310. package/prompts/explore.md +2 -2
  311. package/prompts/git-master.md +2 -2
  312. package/prompts/information-architect.md +15 -102
  313. package/prompts/performance-reviewer.md +2 -2
  314. package/prompts/planner.md +3 -2
  315. package/prompts/product-analyst.md +2 -2
  316. package/prompts/product-manager.md +2 -2
  317. package/prompts/qa-tester.md +2 -2
  318. package/prompts/quality-reviewer.md +2 -2
  319. package/prompts/quality-strategist.md +2 -2
  320. package/prompts/researcher.md +2 -2
  321. package/prompts/security-reviewer.md +2 -2
  322. package/prompts/sisyphus-lite.md +2 -2
  323. package/prompts/style-reviewer.md +2 -2
  324. package/prompts/team-executor.md +2 -2
  325. package/prompts/test-engineer.md +2 -2
  326. package/prompts/ux-researcher.md +2 -2
  327. package/prompts/verifier.md +3 -2
  328. package/prompts/vision.md +2 -2
  329. package/prompts/writer.md +2 -2
  330. package/skills/team/SKILL.md +18 -33
  331. package/src/scripts/__tests__/codex-native-hook.test.ts +1346 -0
  332. package/src/scripts/codex-native-hook.ts +983 -0
  333. package/src/scripts/codex-native-pre-post.ts +161 -0
  334. package/src/scripts/notify-fallback-watcher.ts +378 -29
  335. package/src/scripts/notify-hook/auto-nudge.ts +5 -10
  336. package/src/scripts/notify-hook/log.ts +18 -4
  337. package/src/scripts/notify-hook/managed-tmux.ts +1 -0
  338. package/src/scripts/notify-hook/orchestration-intent.ts +82 -0
  339. package/src/scripts/notify-hook/process-runner.ts +4 -4
  340. package/src/scripts/notify-hook/ralph-session-resume.ts +9 -0
  341. package/src/scripts/notify-hook/team-dispatch.ts +134 -6
  342. package/src/scripts/notify-hook/team-leader-nudge.ts +183 -37
  343. package/src/scripts/notify-hook/team-tmux-guard.ts +35 -43
  344. package/src/scripts/notify-hook/team-worker.ts +73 -4
  345. package/src/scripts/notify-hook/utils.ts +1 -1
  346. package/src/scripts/notify-hook.ts +64 -32
  347. package/templates/AGENTS.md +21 -11
  348. package/README.de.md +0 -263
  349. package/README.el.md +0 -223
  350. package/README.es.md +0 -263
  351. package/README.fr.md +0 -263
  352. package/README.it.md +0 -263
  353. package/README.ja.md +0 -264
  354. package/README.ko.md +0 -264
  355. package/README.pl.md +0 -216
  356. package/README.pt.md +0 -263
  357. package/README.ru.md +0 -263
  358. package/README.tr.md +0 -263
  359. package/README.vi.md +0 -223
  360. package/README.zh-TW.md +0 -293
  361. package/README.zh.md +0 -264
  362. package/dist/mcp/__tests__/team-server-cleanup.test.d.ts +0 -2
  363. package/dist/mcp/__tests__/team-server-cleanup.test.d.ts.map +0 -1
  364. package/dist/mcp/__tests__/team-server-cleanup.test.js +0 -219
  365. package/dist/mcp/__tests__/team-server-cleanup.test.js.map +0 -1
  366. package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts +0 -2
  367. package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts.map +0 -1
  368. package/dist/mcp/__tests__/team-server-runtime-deps.test.js +0 -13
  369. package/dist/mcp/__tests__/team-server-runtime-deps.test.js.map +0 -1
  370. package/dist/mcp/__tests__/team-server-wait.test.d.ts +0 -2
  371. package/dist/mcp/__tests__/team-server-wait.test.d.ts.map +0 -1
  372. package/dist/mcp/__tests__/team-server-wait.test.js +0 -155
  373. package/dist/mcp/__tests__/team-server-wait.test.js.map +0 -1
  374. package/dist/mcp/team-server.d.ts +0 -24
  375. package/dist/mcp/team-server.d.ts.map +0 -1
  376. package/dist/mcp/team-server.js +0 -482
  377. package/dist/mcp/team-server.js.map +0 -1
package/dist/cli/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { execFileSync, spawn } from "child_process";
6
6
  import { basename, dirname, join } from "path";
7
- import { existsSync, readFileSync } from "fs";
7
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
8
8
  import { constants as osConstants } from "os";
9
9
  import { setup, SETUP_SCOPES } from "./setup.js";
10
10
  import { uninstall } from "./uninstall.js";
@@ -30,9 +30,10 @@ import { generateOverlay, removeSessionModelInstructionsFile, resolveSessionOrch
30
30
  import { readSessionState, writeSessionStart, writeSessionEnd, resetSessionMetrics, } from "../hooks/session.js";
31
31
  import { buildClientAttachedReconcileHookName, buildReconcileHudResizeArgs, buildRegisterClientAttachedReconcileArgs, buildRegisterResizeHookArgs, buildResizeHookName, buildResizeHookTarget, buildScheduleDelayedHudResizeArgs, buildUnregisterClientAttachedReconcileArgs, buildUnregisterResizeHookArgs, enableMouseScrolling, isMsysOrGitBash, isNativeWindows, isTmuxAvailable, } from "../team/tmux-session.js";
32
32
  import { getPackageRoot } from "../utils/package.js";
33
- import { codexConfigPath } from "../utils/paths.js";
33
+ import { codexConfigPath, rememberOmxLaunchContext, resolveOmxEntryPath } from "../utils/paths.js";
34
34
  import { repairConfigIfNeeded } from "../config/generator.js";
35
35
  import { HUD_TMUX_HEIGHT_LINES } from "../hud/constants.js";
36
+ rememberOmxLaunchContext();
36
37
  import { classifySpawnError, spawnPlatformCommandSync, } from "../utils/platform-command.js";
37
38
  import { buildHookEvent } from "../hooks/extensibility/events.js";
38
39
  import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
@@ -100,6 +101,7 @@ Options:
100
101
  --madmax-spark spark model for workers + bypass approvals for leader and workers
101
102
  (shorthand for: --spark --madmax)
102
103
  --notify-temp Enable temporary notification routing for this run/session only
104
+ --tmux Launch the interactive leader session in detached tmux
103
105
  --discord Select Discord provider for temporary notification mode
104
106
  --slack Select Slack provider for temporary notification mode
105
107
  --telegram Select Telegram provider for temporary notification mode
@@ -146,6 +148,11 @@ const ALLOWED_SHELLS = new Set([
146
148
  ]);
147
149
  const WINDOWS_DETACHED_BOOTSTRAP_DELAY_MS = 2500;
148
150
  const CODEX_VERSION_FLAGS = new Set(["--version", "-V"]);
151
+ const TMUX_EXTENDED_KEYS_MODE = "always";
152
+ const TMUX_EXTENDED_KEYS_FALLBACK_MODE = "off";
153
+ const TMUX_EXTENDED_KEYS_LEASE_DIR = "tmux-extended-keys";
154
+ const TMUX_EXTENDED_KEYS_LOCK_RETRY_MS = 20;
155
+ const TMUX_EXTENDED_KEYS_LOCK_MAX_ATTEMPTS = 100;
149
156
  const NESTED_HELP_COMMANDS = new Set([
150
157
  "ask",
151
158
  "cleanup",
@@ -258,9 +265,40 @@ export function resolveNotifyTempContract(args, env = process.env) {
258
265
  export function commandOwnsLocalHelp(command) {
259
266
  return NESTED_HELP_COMMANDS.has(command);
260
267
  }
261
- export function resolveCodexLaunchPolicy(env = process.env, _platform = process.platform, tmuxAvailable = isTmuxAvailable(), nativeWindows = isNativeWindows(), stdinIsTTY = Boolean(process.stdin.isTTY), stdoutIsTTY = Boolean(process.stdout.isTTY)) {
268
+ function splitLeaderLaunchPolicyArgs(args) {
269
+ const remainingArgs = [];
270
+ let explicitPolicy;
271
+ let passthroughOnly = false;
272
+ for (const arg of args) {
273
+ if (passthroughOnly) {
274
+ remainingArgs.push(arg);
275
+ continue;
276
+ }
277
+ if (arg === "--") {
278
+ passthroughOnly = true;
279
+ remainingArgs.push(arg);
280
+ continue;
281
+ }
282
+ if (arg === "--tmux") {
283
+ explicitPolicy = "detached-tmux";
284
+ continue;
285
+ }
286
+ remainingArgs.push(arg);
287
+ }
288
+ return { explicitPolicy, remainingArgs };
289
+ }
290
+ export function resolveLeaderLaunchPolicyOverride(args) {
291
+ return splitLeaderLaunchPolicyArgs(args).explicitPolicy;
292
+ }
293
+ export function resolveCodexLaunchPolicy(env = process.env, _platform = process.platform, tmuxAvailable = isTmuxAvailable(), nativeWindows = isNativeWindows(), stdinIsTTY = Boolean(process.stdin.isTTY), stdoutIsTTY = Boolean(process.stdout.isTTY), explicitPolicy) {
262
294
  if (env.TMUX)
263
295
  return "inside-tmux";
296
+ if (explicitPolicy === "detached-tmux")
297
+ return tmuxAvailable ? "detached-tmux" : "direct";
298
+ if (explicitPolicy === "direct")
299
+ return "direct";
300
+ if (_platform === "win32")
301
+ return "direct";
264
302
  if (nativeWindows)
265
303
  return "direct";
266
304
  if (!stdinIsTTY || !stdoutIsTTY)
@@ -622,8 +660,9 @@ export async function launchWithHud(args) {
622
660
  const launchCwd = process.cwd();
623
661
  const parsedWorktree = parseWorktreeMode(args);
624
662
  const notifyTempResult = resolveNotifyTempContract(parsedWorktree.remainingArgs, process.env);
663
+ const explicitLaunchPolicy = resolveLeaderLaunchPolicyOverride(notifyTempResult.passthroughArgs);
625
664
  const codexHomeOverride = resolveCodexHomeForLaunch(launchCwd, process.env);
626
- const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, isNativeWindows());
665
+ const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, isNativeWindows(), undefined, undefined, explicitLaunchPolicy);
627
666
  const enableNotifyFallbackAuthority = launchPolicy === "direct";
628
667
  const workerSparkModel = resolveWorkerSparkModel(notifyTempResult.passthroughArgs, codexHomeOverride);
629
668
  const normalizedArgs = normalizeCodexLaunchArgs(notifyTempResult.passthroughArgs);
@@ -661,7 +700,7 @@ export async function launchWithHud(args) {
661
700
  try {
662
701
  const repaired = await repairConfigIfNeeded(codexConfigPath(), getPackageRoot());
663
702
  if (repaired) {
664
- console.log("[omx] Repaired duplicate [tui] section in config.toml.");
703
+ console.log("[omx] Repaired managed config.toml compatibility issue.");
665
704
  }
666
705
  }
667
706
  catch {
@@ -680,7 +719,7 @@ export async function launchWithHud(args) {
680
719
  const notifyTempContractRaw = notifyTempResult.contract.active
681
720
  ? serializeNotifyTempContract(notifyTempResult.contract)
682
721
  : null;
683
- runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, notifyTempContractRaw);
722
+ runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, notifyTempContractRaw, explicitLaunchPolicy);
684
723
  }
685
724
  finally {
686
725
  // ── Phase 3: postLaunch ─────────────────────────────────────────────
@@ -721,7 +760,7 @@ export async function execWithOverlay(args) {
721
760
  try {
722
761
  const repaired = await repairConfigIfNeeded(codexConfigPath(), getPackageRoot());
723
762
  if (repaired) {
724
- console.log("[omx] Repaired duplicate [tui] section in config.toml.");
763
+ console.log("[omx] Repaired managed config.toml compatibility issue.");
725
764
  }
726
765
  }
727
766
  catch {
@@ -755,11 +794,12 @@ export async function execWithOverlay(args) {
755
794
  }
756
795
  export function normalizeCodexLaunchArgs(args) {
757
796
  const parsed = parseWorktreeMode(args);
797
+ const launchPolicyParsed = splitLeaderLaunchPolicyArgs(parsed.remainingArgs);
758
798
  const normalized = [];
759
799
  let wantsBypass = false;
760
800
  let hasBypass = false;
761
801
  let reasoningMode = null;
762
- for (const arg of parsed.remainingArgs) {
802
+ for (const arg of launchPolicyParsed.remainingArgs) {
763
803
  if (arg === MADMAX_FLAG) {
764
804
  wantsBypass = true;
765
805
  continue;
@@ -1050,20 +1090,191 @@ function detectDetachedSessionWindowIndex(sessionName) {
1050
1090
  function escapeShellDoubleQuotedValue(value) {
1051
1091
  return value.replace(/["\\$`]/g, "\\$&");
1052
1092
  }
1053
- function buildDetachedSessionLeaderCommand(sessionName, codexCmd) {
1054
- const cleanupTrap = [
1093
+ function sanitizeTmuxLeaseKey(value) {
1094
+ const cleaned = value
1095
+ .toLowerCase()
1096
+ .replace(/[^a-z0-9]+/g, "-")
1097
+ .replace(/^-+|-+$/g, "");
1098
+ return cleaned || "default";
1099
+ }
1100
+ function blockMs(ms) {
1101
+ const delay = Math.max(1, Math.floor(ms));
1102
+ const shared = new SharedArrayBuffer(4);
1103
+ const view = new Int32Array(shared);
1104
+ Atomics.wait(view, 0, 0, delay);
1105
+ }
1106
+ function tmuxExtendedKeysLeaseRoot(cwd) {
1107
+ return join(cwd, ".omx", "state", TMUX_EXTENDED_KEYS_LEASE_DIR);
1108
+ }
1109
+ function resolveTmuxSocketPath(execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1110
+ encoding: "utf-8",
1111
+ })) {
1112
+ return (execTmuxSync(["display-message", "-p", "#{socket_path}"], execFileSyncImpl) ||
1113
+ "default");
1114
+ }
1115
+ function tmuxExtendedKeysLeasePath(cwd, socketPath) {
1116
+ return join(tmuxExtendedKeysLeaseRoot(cwd), `${sanitizeTmuxLeaseKey(socketPath)}.json`);
1117
+ }
1118
+ function readTmuxExtendedKeysLeaseState(leasePath) {
1119
+ if (!existsSync(leasePath))
1120
+ return null;
1121
+ try {
1122
+ const parsed = JSON.parse(readFileSync(leasePath, "utf-8"));
1123
+ if (typeof parsed.originalMode !== "string" ||
1124
+ !Array.isArray(parsed.holders) ||
1125
+ !parsed.holders.every((holder) => typeof holder === "string")) {
1126
+ return null;
1127
+ }
1128
+ return {
1129
+ originalMode: parsed.originalMode,
1130
+ holders: [...parsed.holders],
1131
+ };
1132
+ }
1133
+ catch {
1134
+ return null;
1135
+ }
1136
+ }
1137
+ function writeTmuxExtendedKeysLeaseState(leasePath, state) {
1138
+ mkdirSync(dirname(leasePath), { recursive: true });
1139
+ writeFileSync(leasePath, JSON.stringify(state, null, 2));
1140
+ }
1141
+ function withTmuxExtendedKeysLeaseLock(cwd, socketPath, run) {
1142
+ const leaseRoot = tmuxExtendedKeysLeaseRoot(cwd);
1143
+ mkdirSync(leaseRoot, { recursive: true });
1144
+ const lockPath = join(leaseRoot, `${sanitizeTmuxLeaseKey(socketPath)}.lock`);
1145
+ for (let attempt = 0; attempt < TMUX_EXTENDED_KEYS_LOCK_MAX_ATTEMPTS; attempt++) {
1146
+ try {
1147
+ mkdirSync(lockPath);
1148
+ try {
1149
+ return run();
1150
+ }
1151
+ finally {
1152
+ rmSync(lockPath, { recursive: true, force: true });
1153
+ }
1154
+ }
1155
+ catch (err) {
1156
+ const code = err && typeof err === "object" && "code" in err
1157
+ ? String(err.code)
1158
+ : "";
1159
+ if (code !== "EEXIST")
1160
+ throw err;
1161
+ blockMs(TMUX_EXTENDED_KEYS_LOCK_RETRY_MS);
1162
+ }
1163
+ }
1164
+ throw new Error(`timed out waiting for tmux extended-keys lease lock: ${lockPath}`);
1165
+ }
1166
+ function buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd) {
1167
+ const wrapped = [
1168
+ buildTmuxExtendedKeysAcquireShellSnippet(cwd),
1169
+ "omx_detached_session_cleanup() {",
1055
1170
  "status=$?;",
1056
1171
  "trap - 0 INT TERM HUP;",
1172
+ buildTmuxExtendedKeysReleaseShellSnippet(cwd),
1057
1173
  `tmux kill-session -t "${escapeShellDoubleQuotedValue(sessionName)}" >/dev/null 2>&1 || true;`,
1058
1174
  "exit $status;",
1175
+ "};",
1176
+ "trap omx_detached_session_cleanup 0 INT TERM HUP;",
1177
+ codexCmd,
1059
1178
  ].join(" ");
1060
- const wrapped = [`trap '${cleanupTrap}' 0 INT TERM HUP;`, codexCmd].join(" ");
1061
1179
  return `/bin/sh -lc ${quoteShellArg(wrapped)}`;
1062
1180
  }
1181
+ function execTmuxSync(args, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1182
+ encoding: "utf-8",
1183
+ })) {
1184
+ return execFileSyncImpl("tmux", [...args]).trim();
1185
+ }
1186
+ export function acquireTmuxExtendedKeysLease(cwd, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1187
+ encoding: "utf-8",
1188
+ })) {
1189
+ try {
1190
+ const socketPath = resolveTmuxSocketPath(execFileSyncImpl);
1191
+ const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
1192
+ const leaseId = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1193
+ withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
1194
+ const state = readTmuxExtendedKeysLeaseState(leasePath);
1195
+ if (!state || state.holders.length === 0) {
1196
+ const previousMode = execTmuxSync(["show-options", "-sv", "extended-keys"], execFileSyncImpl) ||
1197
+ TMUX_EXTENDED_KEYS_FALLBACK_MODE;
1198
+ execTmuxSync(["set-option", "-sq", "extended-keys", TMUX_EXTENDED_KEYS_MODE], execFileSyncImpl);
1199
+ writeTmuxExtendedKeysLeaseState(leasePath, {
1200
+ originalMode: previousMode,
1201
+ holders: [leaseId],
1202
+ });
1203
+ return;
1204
+ }
1205
+ state.holders.push(leaseId);
1206
+ writeTmuxExtendedKeysLeaseState(leasePath, state);
1207
+ });
1208
+ return `${socketPath}\t${leaseId}`;
1209
+ }
1210
+ catch (err) {
1211
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1212
+ return null;
1213
+ }
1214
+ }
1215
+ export function releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1216
+ encoding: "utf-8",
1217
+ })) {
1218
+ if (!leaseHandle.trim())
1219
+ return;
1220
+ const [socketPathRaw = "", leaseId = ""] = leaseHandle.split("\t");
1221
+ const socketPath = socketPathRaw.trim() || "default";
1222
+ if (!leaseId)
1223
+ return;
1224
+ try {
1225
+ const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
1226
+ withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
1227
+ const state = readTmuxExtendedKeysLeaseState(leasePath);
1228
+ if (!state || state.holders.length === 0) {
1229
+ rmSync(leasePath, { force: true });
1230
+ return;
1231
+ }
1232
+ const holders = state.holders.filter((holder) => holder !== leaseId);
1233
+ if (holders.length > 0) {
1234
+ writeTmuxExtendedKeysLeaseState(leasePath, {
1235
+ originalMode: state.originalMode,
1236
+ holders,
1237
+ });
1238
+ return;
1239
+ }
1240
+ execTmuxSync(["set-option", "-sq", "extended-keys", state.originalMode], execFileSyncImpl);
1241
+ rmSync(leasePath, { force: true });
1242
+ });
1243
+ }
1244
+ catch (err) {
1245
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1246
+ }
1247
+ }
1248
+ function buildTmuxExtendedKeysHelperCommand(cwd, operation) {
1249
+ const cwdLiteral = JSON.stringify(cwd);
1250
+ const moduleUrlLiteral = JSON.stringify(import.meta.url);
1251
+ const script = operation === "acquire"
1252
+ ? `const mod = await import(${moduleUrlLiteral}); const lease = mod.acquireTmuxExtendedKeysLease(${cwdLiteral}); if (lease) process.stdout.write(lease);`
1253
+ : `const mod = await import(${moduleUrlLiteral}); mod.releaseTmuxExtendedKeysLease(${cwdLiteral}, process.argv[1] ?? "");`;
1254
+ return `${quoteShellArg(process.execPath)} --input-type=module -e ${quoteShellArg(script)}`;
1255
+ }
1256
+ function buildTmuxExtendedKeysAcquireShellSnippet(cwd) {
1257
+ return `OMX_TMUX_EXTENDED_KEYS_LEASE=$(${buildTmuxExtendedKeysHelperCommand(cwd, "acquire")} 2>/dev/null || true);`;
1258
+ }
1259
+ function buildTmuxExtendedKeysReleaseShellSnippet(cwd) {
1260
+ return `if [ -n "\${OMX_TMUX_EXTENDED_KEYS_LEASE:-}" ]; then ${buildTmuxExtendedKeysHelperCommand(cwd, "release")} "\${OMX_TMUX_EXTENDED_KEYS_LEASE}" >/dev/null 2>&1 || true; fi;`;
1261
+ }
1262
+ export function withTmuxExtendedKeys(cwd, run, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
1263
+ encoding: "utf-8",
1264
+ })) {
1265
+ const leaseHandle = acquireTmuxExtendedKeysLease(cwd, execFileSyncImpl);
1266
+ try {
1267
+ return run();
1268
+ }
1269
+ finally {
1270
+ if (leaseHandle)
1271
+ releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl);
1272
+ }
1273
+ }
1063
1274
  export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId) {
1064
1275
  const detachedLeaderCmd = nativeWindows
1065
1276
  ? "powershell.exe"
1066
- : buildDetachedSessionLeaderCommand(sessionName, codexCmd);
1277
+ : buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd);
1067
1278
  const newSessionArgs = [
1068
1279
  "new-session",
1069
1280
  "-d",
@@ -1197,6 +1408,13 @@ export function buildNotifyFallbackWatcherEnv(env = process.env, options = {}) {
1197
1408
  OMX_HUD_AUTHORITY: options.enableAuthority ? "1" : "0",
1198
1409
  };
1199
1410
  }
1411
+ export function shouldEnableNotifyFallbackWatcher(env = process.env, platform = process.platform) {
1412
+ const toggle = String(env.OMX_NOTIFY_FALLBACK ?? "").trim();
1413
+ if (platform === "win32") {
1414
+ return toggle === "1";
1415
+ }
1416
+ return toggle !== "0";
1417
+ }
1200
1418
  export async function cleanupLaunchOrphanedMcpProcesses(dependencies = {}) {
1201
1419
  return cleanupOmxMcpProcesses([], {
1202
1420
  ...dependencies,
@@ -1204,6 +1422,24 @@ export async function cleanupLaunchOrphanedMcpProcesses(dependencies = {}) {
1204
1422
  writeLine: dependencies.writeLine ?? (() => { }),
1205
1423
  });
1206
1424
  }
1425
+ export async function reapPostLaunchOrphanedMcpProcesses(dependencies = {}) {
1426
+ const cleanup = dependencies.cleanup ?? cleanupLaunchOrphanedMcpProcesses;
1427
+ const writeInfo = dependencies.writeInfo ?? console.log;
1428
+ const writeWarn = dependencies.writeWarn ?? console.warn;
1429
+ const writeError = dependencies.writeError ?? ((line) => process.stderr.write(line));
1430
+ try {
1431
+ const result = await cleanup();
1432
+ if (result.terminatedCount > 0) {
1433
+ writeInfo(`[omx] postLaunch: reaped ${result.terminatedCount} orphaned OMX MCP process(es).`);
1434
+ }
1435
+ if (result.failedPids.length > 0) {
1436
+ writeWarn(`[omx] postLaunch: failed to reap ${result.failedPids.length} orphaned OMX MCP process(es); continuing cleanup.`);
1437
+ }
1438
+ }
1439
+ catch (err) {
1440
+ writeError(`[cli/index] postLaunch MCP cleanup failed: ${err}\n`);
1441
+ }
1442
+ }
1207
1443
  /**
1208
1444
  * preLaunch: Prepare environment before Codex starts.
1209
1445
  * 1. Best-effort launch-safe orphan cleanup for detached OMX MCP processes
@@ -1307,10 +1543,13 @@ ${launchAppendix}`
1307
1543
  * runCodex: Launch Codex CLI (blocks until exit).
1308
1544
  * All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
1309
1545
  */
1310
- function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, notifyTempContractRaw) {
1546
+ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, notifyTempContractRaw, explicitLaunchPolicy) {
1311
1547
  const launchArgs = injectModelInstructionsBypassArgs(cwd, args, process.env, sessionModelInstructionsPath(cwd, sessionId));
1312
1548
  const nativeWindows = isNativeWindows();
1313
- const omxBin = process.argv[1];
1549
+ const omxBin = resolveOmxEntryPath();
1550
+ if (!omxBin) {
1551
+ throw new Error("Unable to resolve OMX launcher path for tmux HUD bootstrap");
1552
+ }
1314
1553
  const hudCmd = nativeWindows
1315
1554
  ? buildWindowsPromptCommand("node", [omxBin, "hud", "--watch"])
1316
1555
  : buildTmuxPaneCommand("node", [omxBin, "hud", "--watch"]);
@@ -1326,7 +1565,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, n
1326
1565
  const codexEnvWithNotify = notifyTempContractRaw
1327
1566
  ? { ...codexEnv, [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw }
1328
1567
  : codexEnv;
1329
- const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, nativeWindows);
1568
+ const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, nativeWindows, undefined, undefined, explicitLaunchPolicy);
1330
1569
  if (isCodexVersionRequest(launchArgs)) {
1331
1570
  runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
1332
1571
  return;
@@ -1376,7 +1615,9 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, n
1376
1615
  catch { }
1377
1616
  }
1378
1617
  try {
1379
- runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
1618
+ withTmuxExtendedKeys(cwd, () => {
1619
+ runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
1620
+ });
1380
1621
  }
1381
1622
  finally {
1382
1623
  const cleanupPaneIds = buildHudPaneCleanupTargets(listHudWatchPaneIdsInCurrentWindow(currentPaneId), hudPaneId, currentPaneId);
@@ -1598,6 +1839,8 @@ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbac
1598
1839
  process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1599
1840
  // Non-fatal
1600
1841
  }
1842
+ // 0. Reap MCP orphans left behind by the session that just exited.
1843
+ await reapPostLaunchOrphanedMcpProcesses();
1601
1844
  // 0. Flush fallback watcher once to reduce race with fast codex exit.
1602
1845
  try {
1603
1846
  await flushNotifyFallbackOnce(cwd, { codexHomeOverride, enableAuthority: enableNotifyFallbackAuthority, sessionId });
@@ -1685,6 +1928,15 @@ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbac
1685
1928
  process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1686
1929
  // Non-fatal: notification failures must never block session cleanup
1687
1930
  }
1931
+ // 4.5. Persist team leader attention when an active leader session exits.
1932
+ try {
1933
+ const { markOwnedTeamsLeaderSessionStopped } = await import("../team/state.js");
1934
+ await markOwnedTeamsLeaderSessionStopped(cwd, sessionId);
1935
+ }
1936
+ catch (err) {
1937
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1938
+ // Non-fatal
1939
+ }
1688
1940
  // 5. Dispatch native hook event (best effort)
1689
1941
  try {
1690
1942
  const durationMs = sessionStartedAt
@@ -1811,6 +2063,30 @@ function parseWatcherPidFile(content) {
1811
2063
  return Number.isFinite(pid) && pid > 0 ? pid : null;
1812
2064
  }
1813
2065
  }
2066
+ export async function reapStaleNotifyFallbackWatcher(pidPath, deps = {}) {
2067
+ const exists = deps.exists ?? existsSync;
2068
+ if (!exists(pidPath))
2069
+ return;
2070
+ const { readFile } = await import("fs/promises");
2071
+ const readFileImpl = deps.readFile ?? readFile;
2072
+ const tryKillPidImpl = deps.tryKillPid ?? tryKillPid;
2073
+ const hasErrnoCodeImpl = deps.hasErrnoCode ?? hasErrnoCode;
2074
+ const warn = deps.warn ?? console.warn;
2075
+ try {
2076
+ const prevPid = parseWatcherPidFile(await readFileImpl(pidPath, "utf-8"));
2077
+ if (prevPid) {
2078
+ tryKillPidImpl(prevPid, "SIGTERM");
2079
+ }
2080
+ }
2081
+ catch (error) {
2082
+ if (!hasErrnoCodeImpl(error, "ESRCH")) {
2083
+ warn("[omx] warning: failed to stop stale notify fallback watcher", {
2084
+ path: pidPath,
2085
+ error: error instanceof Error ? error.message : String(error),
2086
+ });
2087
+ }
2088
+ }
2089
+ }
1814
2090
  function tryKillPid(pid, signal = "SIGTERM") {
1815
2091
  try {
1816
2092
  process.kill(pid, signal);
@@ -1824,32 +2100,16 @@ function tryKillPid(pid, signal = "SIGTERM") {
1824
2100
  }
1825
2101
  }
1826
2102
  async function startNotifyFallbackWatcher(cwd, options = {}) {
1827
- if (process.env.OMX_NOTIFY_FALLBACK === "0")
1828
- return;
1829
- const { mkdir, writeFile, readFile } = await import("fs/promises");
2103
+ const { mkdir, writeFile } = await import("fs/promises");
1830
2104
  const pidPath = notifyFallbackPidPath(cwd);
2105
+ await reapStaleNotifyFallbackWatcher(pidPath);
2106
+ if (!shouldEnableNotifyFallbackWatcher(process.env, process.platform))
2107
+ return;
1831
2108
  const pkgRoot = getPackageRoot();
1832
2109
  const watcherScript = resolveNotifyFallbackWatcherScript(pkgRoot);
1833
2110
  const notifyScript = resolveNotifyHookScript(pkgRoot);
1834
2111
  if (!existsSync(watcherScript) || !existsSync(notifyScript))
1835
2112
  return;
1836
- // Stop stale watcher from a previous run.
1837
- if (existsSync(pidPath)) {
1838
- try {
1839
- const prevPid = parseWatcherPidFile(await readFile(pidPath, "utf-8"));
1840
- if (prevPid) {
1841
- tryKillPid(prevPid, "SIGTERM");
1842
- }
1843
- }
1844
- catch (error) {
1845
- if (!hasErrnoCode(error, "ESRCH")) {
1846
- console.warn("[omx] warning: failed to stop stale notify fallback watcher", {
1847
- path: pidPath,
1848
- error: error instanceof Error ? error.message : String(error),
1849
- });
1850
- }
1851
- }
1852
- }
1853
2113
  await mkdir(join(cwd, ".omx", "state"), { recursive: true }).catch((error) => {
1854
2114
  console.warn("[omx] warning: failed to create notify fallback watcher state directory", {
1855
2115
  cwd,
@@ -2003,6 +2263,8 @@ async function stopHookDerivedWatcher(cwd) {
2003
2263
  });
2004
2264
  }
2005
2265
  async function flushNotifyFallbackOnce(cwd, options = {}) {
2266
+ if (!shouldEnableNotifyFallbackWatcher(process.env, process.platform))
2267
+ return;
2006
2268
  const { spawnSync } = await import("child_process");
2007
2269
  const pkgRoot = getPackageRoot();
2008
2270
  const watcherScript = resolveNotifyFallbackWatcherScript(pkgRoot);