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
@@ -6,7 +6,7 @@ import { dirname, join } from "node:path";
6
6
  import { tmpdir } from "node:os";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { once } from "node:events";
9
- import { HELP, normalizeCodexLaunchArgs, buildTmuxShellCommand, buildTmuxPaneCommand, buildWindowsPromptCommand, buildTmuxSessionName, resolveCliInvocation, commandOwnsLocalHelp, resolveCodexLaunchPolicy, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupScopeArg, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript, buildDetachedWindowsBootstrapScript, acquireTmuxExtendedKeysLease, resolveNativeSessionName, releaseTmuxExtendedKeysLease, withTmuxExtendedKeys, } from "../index.js";
9
+ import { HELP, normalizeCodexLaunchArgs, buildTmuxShellCommand, buildTmuxPaneCommand, buildWindowsPromptCommand, buildTmuxSessionName, resolveCliInvocation, commandOwnsLocalHelp, resolveCodexLaunchPolicy, resolveEffectiveLeaderLaunchPolicyOverride, resolveEnvLaunchPolicyOverride, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupScopeArg, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript, buildDetachedWindowsBootstrapScript, acquireTmuxExtendedKeysLease, resolveNativeSessionName, releaseTmuxExtendedKeysLease, withTmuxExtendedKeys, } from "../index.js";
10
10
  import { ensureReusableNodeModules } from "../../utils/repo-deps.js";
11
11
  import { readAllState } from "../../hud/state.js";
12
12
  import { generateOverlay } from "../../hooks/agents-overlay.js";
@@ -138,6 +138,11 @@ describe("normalizeCodexLaunchArgs", () => {
138
138
  "--yolo",
139
139
  ]);
140
140
  });
141
+ it("strips --direct from leader codex args", () => {
142
+ assert.deepEqual(normalizeCodexLaunchArgs(["--direct", "--yolo"]), [
143
+ "--yolo",
144
+ ]);
145
+ });
141
146
  it("preserves literal --tmux after -- in leader codex args", () => {
142
147
  assert.deepEqual(normalizeCodexLaunchArgs(["--", "--tmux", "--yolo"]), [
143
148
  "--",
@@ -145,17 +150,64 @@ describe("normalizeCodexLaunchArgs", () => {
145
150
  "--yolo",
146
151
  ]);
147
152
  });
153
+ it("preserves literal --direct after -- in leader codex args", () => {
154
+ assert.deepEqual(normalizeCodexLaunchArgs(["--", "--direct", "--yolo"]), [
155
+ "--",
156
+ "--direct",
157
+ "--yolo",
158
+ ]);
159
+ });
148
160
  });
149
161
  describe("resolveLeaderLaunchPolicyOverride", () => {
150
162
  it("detects explicit detached tmux launch requests", () => {
151
163
  assert.equal(resolveLeaderLaunchPolicyOverride(["--tmux", "--model", "gpt-5"]), "detached-tmux");
152
164
  });
165
+ it("detects explicit direct launch requests", () => {
166
+ assert.equal(resolveLeaderLaunchPolicyOverride(["--direct", "--model", "gpt-5"]), "direct");
167
+ });
168
+ it("uses the last CLI launch policy flag before --", () => {
169
+ assert.equal(resolveLeaderLaunchPolicyOverride(["--direct", "--tmux"]), "detached-tmux");
170
+ assert.equal(resolveLeaderLaunchPolicyOverride(["--tmux", "--direct"]), "direct");
171
+ });
153
172
  it("returns undefined when no explicit policy override is present", () => {
154
173
  assert.equal(resolveLeaderLaunchPolicyOverride(["--model", "gpt-5"]), undefined);
155
174
  });
156
175
  it("stops scanning for --tmux after the end-of-options marker", () => {
157
176
  assert.equal(resolveLeaderLaunchPolicyOverride(["--", "--tmux", "--model", "gpt-5"]), undefined);
158
177
  });
178
+ it("stops scanning for --direct after the end-of-options marker", () => {
179
+ assert.equal(resolveLeaderLaunchPolicyOverride(["--", "--direct", "--model", "gpt-5"]), undefined);
180
+ });
181
+ });
182
+ describe("resolveEnvLaunchPolicyOverride", () => {
183
+ it("accepts direct, tmux, detached-tmux, auto, and empty policy values", () => {
184
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "direct" }), "direct");
185
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "tmux" }), "detached-tmux");
186
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "detached-tmux" }), "detached-tmux");
187
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "auto" }), undefined);
188
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "" }), undefined);
189
+ });
190
+ it("warns once for invalid OMX_LAUNCH_POLICY and falls back to auto", () => {
191
+ const warn = mock.method(console, "warn", () => { });
192
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "banana" }), undefined);
193
+ assert.equal(resolveEnvLaunchPolicyOverride({ OMX_LAUNCH_POLICY: "banana" }), undefined);
194
+ assert.equal(warn.mock.callCount(), 1);
195
+ });
196
+ });
197
+ describe("resolveEffectiveLeaderLaunchPolicyOverride", () => {
198
+ it("uses env policy when no CLI policy flag is present", () => {
199
+ assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--yolo"], {
200
+ OMX_LAUNCH_POLICY: "direct",
201
+ }), "direct");
202
+ });
203
+ it("lets CLI policy flags override OMX_LAUNCH_POLICY", () => {
204
+ assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--tmux", "--yolo"], {
205
+ OMX_LAUNCH_POLICY: "direct",
206
+ }), "detached-tmux");
207
+ assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--direct", "--yolo"], {
208
+ OMX_LAUNCH_POLICY: "tmux",
209
+ }), "direct");
210
+ });
159
211
  });
160
212
  describe("resolveNotifyTempContract", () => {
161
213
  it("activates from --notify-temp with no providers", () => {
@@ -717,13 +769,31 @@ describe("resolveCliInvocation", () => {
717
769
  it("advertises the explicit update command in top-level help", () => {
718
770
  assert.match(HELP, /omx update\s+Check npm now, update the global install immediately, then refresh setup/);
719
771
  });
772
+ it("advertises direct launch policy controls in top-level help", () => {
773
+ assert.match(HELP, /--direct\s+Launch the interactive leader directly/);
774
+ assert.match(HELP, /OMX_LAUNCH_POLICY=direct\|tmux\|detached-tmux\|auto/);
775
+ assert.match(HELP, /unset OMX_LAUNCH_POLICY/);
776
+ assert.match(HELP, /omx --direct --yolo/);
777
+ assert.match(HELP, /OMX_LAUNCH_POLICY=direct omx --tmux --yolo/);
778
+ assert.match(HELP, /Config files are intentionally not used/);
779
+ });
720
780
  });
721
781
  describe("resolveSetupInstallModeArg", () => {
722
- it("maps --plugin to plugin install mode", () => {
782
+ it("maps explicit setup install mode flags", () => {
723
783
  assert.equal(resolveSetupInstallModeArg(["--dry-run"]), undefined);
724
784
  assert.equal(resolveSetupInstallModeArg(["--plugin"]), "plugin");
785
+ assert.equal(resolveSetupInstallModeArg(["--legacy"]), "legacy");
786
+ assert.equal(resolveSetupInstallModeArg(["--install-mode", "legacy"]), "legacy");
787
+ assert.equal(resolveSetupInstallModeArg(["--install-mode=plugin"]), "plugin");
725
788
  assert.equal(resolveSetupInstallModeArg(["--scope", "project", "--plugin"]), "plugin");
726
789
  });
790
+ it("rejects invalid setup install mode flags", () => {
791
+ assert.throws(() => resolveSetupInstallModeArg(["--install-mode"]), /Missing setup install mode value after --install-mode/);
792
+ assert.throws(() => resolveSetupInstallModeArg(["--install-mode", "workspace"]), /Invalid setup install mode: workspace/);
793
+ assert.throws(() => resolveSetupInstallModeArg(["--plugin", "--legacy"]), /Conflicting setup install mode flags/);
794
+ assert.throws(() => resolveSetupInstallModeArg(["--plugin", "--install-mode", "legacy"]), /Conflicting setup install mode flags/);
795
+ assert.throws(() => resolveSetupInstallModeArg(["--legacy", "--install-mode=plugin"]), /Conflicting setup install mode flags/);
796
+ });
727
797
  });
728
798
  describe("resolveSetupScopeArg", () => {
729
799
  it("returns undefined when scope is omitted", () => {
@@ -815,6 +885,30 @@ describe("project launch scope helpers", () => {
815
885
  await rm(wd, { recursive: true, force: true });
816
886
  }
817
887
  });
888
+ it("marks only persisted project CODEX_HOME as project-local cleanup target", async () => {
889
+ const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
890
+ try {
891
+ await mkdir(join(wd, ".omx"), { recursive: true });
892
+ await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "project" }));
893
+ assert.equal(resolveProjectLocalCodexHomeForLaunch(wd, {}), join(wd, ".codex"));
894
+ }
895
+ finally {
896
+ await rm(wd, { recursive: true, force: true });
897
+ }
898
+ });
899
+ it("does not mark explicit CODEX_HOME as project-local cleanup target", async () => {
900
+ const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
901
+ try {
902
+ await mkdir(join(wd, ".omx"), { recursive: true });
903
+ await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "project" }));
904
+ assert.equal(resolveProjectLocalCodexHomeForLaunch(wd, {
905
+ CODEX_HOME: "/tmp/user-global-codex-home",
906
+ }), undefined);
907
+ }
908
+ finally {
909
+ await rm(wd, { recursive: true, force: true });
910
+ }
911
+ });
818
912
  it("keeps explicit CODEX_HOME override from env", async () => {
819
913
  const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
820
914
  try {
@@ -886,6 +980,18 @@ describe("resolveCodexLaunchPolicy", () => {
886
980
  it("honors explicit detached tmux launch requests when tmux is available", () => {
887
981
  assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, true, "detached-tmux"), "detached-tmux");
888
982
  });
983
+ it("honors explicit direct launch requests outside tmux", () => {
984
+ assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, true, "direct"), "direct");
985
+ });
986
+ it("honors explicit direct launch requests inside tmux", () => {
987
+ assert.equal(resolveCodexLaunchPolicy({ TMUX: "/tmp/tmux-1000/default,123,0" }, "linux", true, false, true, true, "direct"), "direct");
988
+ });
989
+ it("keeps explicit tmux policy tmux-aware inside tmux", () => {
990
+ assert.equal(resolveCodexLaunchPolicy({ TMUX: "/tmp/tmux-1000/default,123,0" }, "linux", true, false, true, true, "detached-tmux"), "inside-tmux");
991
+ });
992
+ it("falls back directly for explicit tmux requests when tmux is unavailable", () => {
993
+ assert.equal(resolveCodexLaunchPolicy({}, "linux", false, false, true, true, "detached-tmux"), "direct");
994
+ });
889
995
  it("launches directly when stdin is not a tty outside tmux", () => {
890
996
  assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, false, true), "direct");
891
997
  });
@@ -1037,9 +1143,18 @@ describe("detached tmux new-session sequencing", () => {
1037
1143
  it("buildDetachedSessionBootstrapSteps forwards OMX_SESSION_ID to detached tmux session", () => {
1038
1144
  const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'env' 'OMX_SESSION_ID=sess-detached-managed' 'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, undefined, null, false, "sess-detached-managed");
1039
1145
  const newSession = steps.find((step) => step.name === "new-session");
1146
+ const tagSession = steps.find((step) => step.name === "tag-session");
1040
1147
  assert.ok(newSession);
1148
+ assert.ok(tagSession);
1041
1149
  assert.equal(newSession.args.includes("-e") &&
1042
1150
  newSession.args.some((arg) => arg === "OMX_SESSION_ID=sess-detached-managed"), true);
1151
+ assert.deepEqual(tagSession.args, [
1152
+ "set-option",
1153
+ "-t",
1154
+ "omx-demo",
1155
+ "@omx_instance_id",
1156
+ "sess-detached-managed",
1157
+ ]);
1043
1158
  });
1044
1159
  it("buildDetachedSessionBootstrapSteps forwards CODEX_HOME override to detached tmux session", () => {
1045
1160
  const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, "/tmp/project/.codex", null, false, "sess-detached-managed");
@@ -1050,7 +1165,7 @@ describe("detached tmux new-session sequencing", () => {
1050
1165
  });
1051
1166
  it("runCodex builds inside-tmux HUD command with OMX_SESSION_ID", async () => {
1052
1167
  const source = await readFile(join(repoRoot, 'src', 'cli', 'index.ts'), 'utf-8');
1053
- assert.match(source, /buildTmuxPaneCommand\("env", \[`OMX_SESSION_ID=\$\{sessionId\}`, "node", omxBin, "hud", "--watch"\]\)/);
1168
+ assert.match(source, /buildTmuxPaneCommand\("env",\s*\[\s*`OMX_SESSION_ID=\$\{sessionId\}`,\s*"node",\s*omxBin,\s*"hud",\s*"--watch",?\s*\]\)/);
1054
1169
  });
1055
1170
  it("buildDetachedSessionBootstrapSteps starts native Windows detached sessions with powershell", () => {
1056
1171
  const hudCmd = buildWindowsPromptCommand("node", [
@@ -1352,6 +1467,25 @@ exit 0
1352
1467
  ["set-option", "-sq", "extended-keys", "off"],
1353
1468
  ]);
1354
1469
  });
1470
+ it("acquireTmuxExtendedKeysLease can bind lease liveness to a long-lived owner pid", async () => {
1471
+ const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-lease-owner-pid-"));
1472
+ try {
1473
+ const execStub = (_file, args) => {
1474
+ if (args[0] === "display-message")
1475
+ return "/tmp/tmux-owner-pid.sock\n";
1476
+ if (args[0] === "show-options")
1477
+ return "off\n";
1478
+ return "";
1479
+ };
1480
+ const lease = acquireTmuxExtendedKeysLease(cwd, execStub, 12345);
1481
+ assert.match(lease ?? "", /^\/tmp\/tmux-owner-pid\.sock\t12345-/);
1482
+ if (lease)
1483
+ releaseTmuxExtendedKeysLease(cwd, lease, execStub);
1484
+ }
1485
+ finally {
1486
+ await rm(cwd, { recursive: true, force: true });
1487
+ }
1488
+ });
1355
1489
  it("overlapping tmux extended-keys leases restore only after the last holder exits", async () => {
1356
1490
  const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-lease-overlap-"));
1357
1491
  const calls = [];
@@ -1494,6 +1628,145 @@ exit 0
1494
1628
  releaseTmuxExtendedKeysLease(cwd, lease, execStub);
1495
1629
  await rm(cwd, { recursive: true, force: true });
1496
1630
  });
1631
+ it("acquireTmuxExtendedKeysLease reaps dead holders and restores before taking a new lease", async () => {
1632
+ const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-dead-holder-acquire-"));
1633
+ try {
1634
+ const leaseDir = join(cwd, ".omx", "state", "tmux-extended-keys");
1635
+ const leasePath = join(leaseDir, "tmp-stale-holder-sock.json");
1636
+ await mkdir(leaseDir, { recursive: true });
1637
+ await writeFile(leasePath, JSON.stringify({
1638
+ originalMode: "off",
1639
+ holders: ["2147483647-stale-holder"],
1640
+ }), "utf-8");
1641
+ const calls = [];
1642
+ const execStub = (_file, args) => {
1643
+ calls.push([...args]);
1644
+ if (args[0] === "display-message")
1645
+ return "/tmp/stale-holder.sock\n";
1646
+ if (args[0] === "show-options")
1647
+ return "off\n";
1648
+ return "";
1649
+ };
1650
+ const lease = acquireTmuxExtendedKeysLease(cwd, execStub);
1651
+ assert.equal(typeof lease, "string");
1652
+ const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
1653
+ assert.equal(persisted.holders.length, 1);
1654
+ const holder = persisted.holders[0];
1655
+ const holderId = typeof holder === "string" ? holder : holder?.id ?? "";
1656
+ assert.match(holderId, new RegExp(`^${process.pid}-`));
1657
+ assert.equal(typeof holder === "object" ? holder.pid : process.pid, process.pid);
1658
+ assert.doesNotMatch(JSON.stringify(persisted), /2147483647-stale-holder/);
1659
+ if (lease)
1660
+ releaseTmuxExtendedKeysLease(cwd, lease, execStub);
1661
+ assert.deepEqual(calls, [
1662
+ ["display-message", "-p", "#{socket_path}"],
1663
+ ["set-option", "-sq", "extended-keys", "off"],
1664
+ ["show-options", "-sv", "extended-keys"],
1665
+ ["set-option", "-sq", "extended-keys", "always"],
1666
+ ["set-option", "-sq", "extended-keys", "off"],
1667
+ ]);
1668
+ }
1669
+ finally {
1670
+ await rm(cwd, { recursive: true, force: true });
1671
+ }
1672
+ });
1673
+ it("releaseTmuxExtendedKeysLease preserves live legacy string holders", async () => {
1674
+ const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-live-legacy-holder-"));
1675
+ try {
1676
+ const leaseDir = join(cwd, ".omx", "state", "tmux-extended-keys");
1677
+ const leasePath = join(leaseDir, "tmp-live-legacy-sock.json");
1678
+ const legacyHolder = `${process.pid}-legacy-holder`;
1679
+ await mkdir(leaseDir, { recursive: true });
1680
+ await writeFile(leasePath, JSON.stringify({
1681
+ originalMode: "off",
1682
+ holders: [legacyHolder],
1683
+ }), "utf-8");
1684
+ const calls = [];
1685
+ const execStub = (_file, args) => {
1686
+ calls.push([...args]);
1687
+ return "";
1688
+ };
1689
+ releaseTmuxExtendedKeysLease(cwd, "/tmp/live-legacy.sock\tmissing-holder", execStub);
1690
+ const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
1691
+ assert.deepEqual(persisted.holders, [legacyHolder]);
1692
+ assert.deepEqual(calls, [], "live legacy string holders should not be restored away");
1693
+ }
1694
+ finally {
1695
+ await rm(cwd, { recursive: true, force: true });
1696
+ }
1697
+ });
1698
+ it("acquireTmuxExtendedKeysLease reaps Linux PID-reuse identity mismatches", async () => {
1699
+ const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-pid-reuse-holder-"));
1700
+ try {
1701
+ const leaseDir = join(cwd, ".omx", "state", "tmux-extended-keys");
1702
+ const leasePath = join(leaseDir, "tmp-pid-reuse-sock.json");
1703
+ await mkdir(leaseDir, { recursive: true });
1704
+ await writeFile(leasePath, JSON.stringify({
1705
+ originalMode: "off",
1706
+ holders: [{
1707
+ id: `${process.pid}-reused-holder`,
1708
+ pid: process.pid,
1709
+ platform: "linux",
1710
+ linuxStartTicks: -1,
1711
+ }],
1712
+ }), "utf-8");
1713
+ const calls = [];
1714
+ const execStub = (_file, args) => {
1715
+ calls.push([...args]);
1716
+ if (args[0] === "display-message")
1717
+ return "/tmp/pid-reuse.sock\n";
1718
+ if (args[0] === "show-options")
1719
+ return "off\n";
1720
+ return "";
1721
+ };
1722
+ const lease = acquireTmuxExtendedKeysLease(cwd, execStub);
1723
+ assert.equal(typeof lease, "string");
1724
+ const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
1725
+ const holderIds = persisted.holders.map((holder) => typeof holder === "string" ? holder : holder.id ?? "");
1726
+ if (process.platform === "linux") {
1727
+ assert.equal(persisted.holders.length, 1);
1728
+ assert.match(holderIds[0] ?? "", new RegExp(`^${process.pid}-`));
1729
+ assert.doesNotMatch(JSON.stringify(persisted), /reused-holder/);
1730
+ assert.deepEqual(calls, [
1731
+ ["display-message", "-p", "#{socket_path}"],
1732
+ ["set-option", "-sq", "extended-keys", "off"],
1733
+ ["show-options", "-sv", "extended-keys"],
1734
+ ["set-option", "-sq", "extended-keys", "always"],
1735
+ ]);
1736
+ }
1737
+ else {
1738
+ assert.ok(holderIds.includes(`${process.pid}-reused-holder`));
1739
+ }
1740
+ if (lease)
1741
+ releaseTmuxExtendedKeysLease(cwd, lease, execStub);
1742
+ }
1743
+ finally {
1744
+ await rm(cwd, { recursive: true, force: true });
1745
+ }
1746
+ });
1747
+ it("releaseTmuxExtendedKeysLease restores when all remaining holders are dead", async () => {
1748
+ const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-dead-holder-release-"));
1749
+ try {
1750
+ const leaseDir = join(cwd, ".omx", "state", "tmux-extended-keys");
1751
+ const leasePath = join(leaseDir, "tmp-dead-release-sock.json");
1752
+ await mkdir(leaseDir, { recursive: true });
1753
+ await writeFile(leasePath, JSON.stringify({
1754
+ originalMode: "off",
1755
+ holders: ["2147483647-stale-holder"],
1756
+ }), "utf-8");
1757
+ const calls = [];
1758
+ const execStub = (_file, args) => {
1759
+ calls.push([...args]);
1760
+ return "";
1761
+ };
1762
+ releaseTmuxExtendedKeysLease(cwd, "/tmp/dead-release.sock\tmissing-holder", execStub);
1763
+ assert.ok(!existsSync(leasePath), "stale-only lease file should be removed");
1764
+ assert.deepEqual(calls, [["set-option", "-sq", "extended-keys", "off"]]);
1765
+ }
1766
+ finally {
1767
+ await rm(cwd, { recursive: true, force: true });
1768
+ }
1769
+ });
1497
1770
  it("buildDetachedSessionFinalizeSteps keeps schedule after split-capture and before attach", () => {
1498
1771
  const steps = buildDetachedSessionFinalizeSteps("omx-demo", "%12", "3", true);
1499
1772
  const names = steps.map((step) => step.name);
@@ -1578,6 +1851,12 @@ describe("buildTmuxPaneCommand", () => {
1578
1851
  assert.ok(!result.startsWith("'/bin/sh' -c "), "should not fall back to /bin/sh for supported Homebrew zsh");
1579
1852
  assert.ok(result.includes("source ~/.zshrc"), "should source .zshrc");
1580
1853
  });
1854
+ it("keeps MacPorts zsh instead of downgrading to /bin/sh", () => {
1855
+ const result = buildTmuxPaneCommand("codex", ["--model", "gpt-5"], "/opt/local/bin/zsh");
1856
+ assert.ok(result.startsWith("'/opt/local/bin/zsh' -c "), "should preserve MacPorts zsh when SHELL points to it");
1857
+ assert.ok(!result.startsWith("'/bin/sh' -c "), "should not fall back to /bin/sh for supported MacPorts zsh");
1858
+ assert.ok(result.includes("source ~/.zshrc"), "should source .zshrc");
1859
+ });
1581
1860
  it("wraps command with bash profile sourcing while preserving tmux cwd", () => {
1582
1861
  const result = buildTmuxPaneCommand("codex", [], "/bin/bash");
1583
1862
  assert.ok(result.startsWith("'/bin/bash' -c "), "should start with bash non-login shell to preserve tmux cwd");
@@ -1738,6 +2017,16 @@ describe("team worker launch arg inheritance helpers", () => {
1738
2017
  it("collectInheritableTeamWorkerArgs supports --model=<value> syntax", () => {
1739
2018
  assert.deepEqual(collectInheritableTeamWorkerArgs(["--model=gpt-5.3-codex"]), ["--model", "gpt-5.3-codex"]);
1740
2019
  });
2020
+ it("collectInheritableTeamWorkerArgs preserves only safe model_provider config overrides", () => {
2021
+ assert.deepEqual(collectInheritableTeamWorkerArgs([
2022
+ "-c",
2023
+ 'sandbox_mode="danger-full-access"',
2024
+ "-c",
2025
+ 'model_provider="cheapRouter"',
2026
+ "--model",
2027
+ "gpt-5.5",
2028
+ ]), ["-c", 'model_provider="cheapRouter"', "--model", "gpt-5.5"]);
2029
+ });
1741
2030
  it("resolveTeamWorkerLaunchArgsEnv merges and normalizes with de-dupe + last reasoning/model wins", () => {
1742
2031
  assert.equal(resolveTeamWorkerLaunchArgsEnv('--dangerously-bypass-approvals-and-sandbox -c model_reasoning_effort="high" --model old-a --no-alt-screen --model=old-b', [
1743
2032
  "-c",