oh-my-codex 0.16.0 → 0.16.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 (357) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +2 -2
  4. package/crates/omx-explore/src/main.rs +434 -28
  5. package/dist/agents/__tests__/native-config.test.js +50 -0
  6. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  7. package/dist/agents/native-config.d.ts.map +1 -1
  8. package/dist/agents/native-config.js +3 -2
  9. package/dist/agents/native-config.js.map +1 -1
  10. package/dist/cli/__tests__/codex-plugin-layout.test.js +1 -0
  11. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  12. package/dist/cli/__tests__/doctor-warning-copy.test.js +1 -1
  13. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  14. package/dist/cli/__tests__/explore.test.js +120 -3
  15. package/dist/cli/__tests__/explore.test.js.map +1 -1
  16. package/dist/cli/__tests__/imagegen-continuation.test.d.ts +2 -0
  17. package/dist/cli/__tests__/imagegen-continuation.test.d.ts.map +1 -0
  18. package/dist/cli/__tests__/imagegen-continuation.test.js +135 -0
  19. package/dist/cli/__tests__/imagegen-continuation.test.js.map +1 -0
  20. package/dist/cli/__tests__/index.test.js +182 -18
  21. package/dist/cli/__tests__/index.test.js.map +1 -1
  22. package/dist/cli/__tests__/launch-fallback.test.js +88 -2
  23. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  24. package/dist/cli/__tests__/ralph.test.js +62 -0
  25. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  26. package/dist/cli/__tests__/setup-install-mode.test.js +48 -0
  27. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  28. package/dist/cli/__tests__/setup-scope.test.js +12 -0
  29. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  30. package/dist/cli/__tests__/team.test.js +465 -12
  31. package/dist/cli/__tests__/team.test.js.map +1 -1
  32. package/dist/cli/__tests__/ultragoal.test.js +50 -5
  33. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  34. package/dist/cli/__tests__/uninstall.test.js +6 -2
  35. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  36. package/dist/cli/explore.d.ts.map +1 -1
  37. package/dist/cli/explore.js +211 -12
  38. package/dist/cli/explore.js.map +1 -1
  39. package/dist/cli/index.d.ts +11 -3
  40. package/dist/cli/index.d.ts.map +1 -1
  41. package/dist/cli/index.js +124 -18
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/cli/ralph.d.ts.map +1 -1
  44. package/dist/cli/ralph.js +37 -3
  45. package/dist/cli/ralph.js.map +1 -1
  46. package/dist/cli/setup.d.ts.map +1 -1
  47. package/dist/cli/setup.js +100 -9
  48. package/dist/cli/setup.js.map +1 -1
  49. package/dist/cli/team.d.ts +1 -0
  50. package/dist/cli/team.d.ts.map +1 -1
  51. package/dist/cli/team.js +42 -7
  52. package/dist/cli/team.js.map +1 -1
  53. package/dist/cli/ultragoal.d.ts +1 -1
  54. package/dist/cli/ultragoal.d.ts.map +1 -1
  55. package/dist/cli/ultragoal.js +29 -8
  56. package/dist/cli/ultragoal.js.map +1 -1
  57. package/dist/cli/uninstall.d.ts.map +1 -1
  58. package/dist/cli/uninstall.js +2 -1
  59. package/dist/cli/uninstall.js.map +1 -1
  60. package/dist/config/__tests__/codex-hooks.test.js +97 -2
  61. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  62. package/dist/config/__tests__/generator-idempotent.test.js +1 -1
  63. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  64. package/dist/config/__tests__/generator-notify.test.js +22 -0
  65. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  66. package/dist/config/__tests__/models.test.js +18 -1
  67. package/dist/config/__tests__/models.test.js.map +1 -1
  68. package/dist/config/__tests__/wiki-config-contract.test.js +2 -1
  69. package/dist/config/__tests__/wiki-config-contract.test.js.map +1 -1
  70. package/dist/config/codex-hooks.d.ts +17 -3
  71. package/dist/config/codex-hooks.d.ts.map +1 -1
  72. package/dist/config/codex-hooks.js +102 -2
  73. package/dist/config/codex-hooks.js.map +1 -1
  74. package/dist/config/generator.d.ts +4 -1
  75. package/dist/config/generator.d.ts.map +1 -1
  76. package/dist/config/generator.js +69 -12
  77. package/dist/config/generator.js.map +1 -1
  78. package/dist/config/models.d.ts +6 -0
  79. package/dist/config/models.d.ts.map +1 -1
  80. package/dist/config/models.js +37 -0
  81. package/dist/config/models.js.map +1 -1
  82. package/dist/exec/followup.d.ts +1 -0
  83. package/dist/exec/followup.d.ts.map +1 -1
  84. package/dist/exec/followup.js +9 -3
  85. package/dist/exec/followup.js.map +1 -1
  86. package/dist/hooks/__tests__/anti-slop-workflow.test.js +19 -0
  87. package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
  88. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +19 -2
  89. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
  90. package/dist/hooks/__tests__/deep-interview-contract.test.js +40 -0
  91. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
  92. package/dist/hooks/__tests__/foreground-isolation-contract.test.d.ts +2 -0
  93. package/dist/hooks/__tests__/foreground-isolation-contract.test.d.ts.map +1 -0
  94. package/dist/hooks/__tests__/foreground-isolation-contract.test.js +28 -0
  95. package/dist/hooks/__tests__/foreground-isolation-contract.test.js.map +1 -0
  96. package/dist/hooks/__tests__/keyword-detector.test.js +37 -25
  97. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  98. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +10 -4
  99. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  100. package/dist/hooks/__tests__/session.test.js +32 -0
  101. package/dist/hooks/__tests__/session.test.js.map +1 -1
  102. package/dist/hooks/__tests__/wiki-docs-contract.test.js +6 -4
  103. package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +1 -1
  104. package/dist/hooks/codebase-map.d.ts.map +1 -1
  105. package/dist/hooks/codebase-map.js +3 -2
  106. package/dist/hooks/codebase-map.js.map +1 -1
  107. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  108. package/dist/hooks/extensibility/dispatcher.js +6 -4
  109. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  110. package/dist/hooks/extensibility/logging.d.ts.map +1 -1
  111. package/dist/hooks/extensibility/logging.js +3 -2
  112. package/dist/hooks/extensibility/logging.js.map +1 -1
  113. package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
  114. package/dist/hooks/extensibility/sdk/paths.js +4 -3
  115. package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
  116. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  117. package/dist/hooks/keyword-detector.js +2 -4
  118. package/dist/hooks/keyword-detector.js.map +1 -1
  119. package/dist/hooks/session.d.ts.map +1 -1
  120. package/dist/hooks/session.js +22 -12
  121. package/dist/hooks/session.js.map +1 -1
  122. package/dist/hud/__tests__/hud-tmux-injection.test.js +8 -7
  123. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  124. package/dist/hud/__tests__/reconcile.test.js +1 -1
  125. package/dist/hud/__tests__/state.test.js +24 -0
  126. package/dist/hud/__tests__/state.test.js.map +1 -1
  127. package/dist/hud/index.js +1 -1
  128. package/dist/hud/index.js.map +1 -1
  129. package/dist/hud/state.d.ts.map +1 -1
  130. package/dist/hud/state.js +22 -8
  131. package/dist/hud/state.js.map +1 -1
  132. package/dist/hud/tmux.js +1 -1
  133. package/dist/hud/tmux.js.map +1 -1
  134. package/dist/imagegen/continuation.d.ts +44 -0
  135. package/dist/imagegen/continuation.d.ts.map +1 -0
  136. package/dist/imagegen/continuation.js +220 -0
  137. package/dist/imagegen/continuation.js.map +1 -0
  138. package/dist/mcp/__tests__/bootstrap.test.js +47 -2
  139. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
  140. package/dist/mcp/__tests__/server-lifecycle.test.js +49 -1
  141. package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
  142. package/dist/mcp/__tests__/state-server.test.js +145 -6
  143. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  144. package/dist/mcp/__tests__/wiki-server.test.js +97 -1
  145. package/dist/mcp/__tests__/wiki-server.test.js.map +1 -1
  146. package/dist/mcp/bootstrap.d.ts +2 -0
  147. package/dist/mcp/bootstrap.d.ts.map +1 -1
  148. package/dist/mcp/bootstrap.js +95 -15
  149. package/dist/mcp/bootstrap.js.map +1 -1
  150. package/dist/mcp/lifecycle-telemetry.d.ts +16 -0
  151. package/dist/mcp/lifecycle-telemetry.d.ts.map +1 -0
  152. package/dist/mcp/lifecycle-telemetry.js +95 -0
  153. package/dist/mcp/lifecycle-telemetry.js.map +1 -0
  154. package/dist/mcp/wiki-server.d.ts.map +1 -1
  155. package/dist/mcp/wiki-server.js +11 -2
  156. package/dist/mcp/wiki-server.js.map +1 -1
  157. package/dist/pipeline/__tests__/stages.test.js +274 -5
  158. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  159. package/dist/pipeline/stages/team-exec.d.ts +2 -0
  160. package/dist/pipeline/stages/team-exec.d.ts.map +1 -1
  161. package/dist/pipeline/stages/team-exec.js +51 -26
  162. package/dist/pipeline/stages/team-exec.js.map +1 -1
  163. package/dist/planning/__tests__/artifacts.test.js +138 -3
  164. package/dist/planning/__tests__/artifacts.test.js.map +1 -1
  165. package/dist/planning/__tests__/context-pack-status.test.d.ts +2 -0
  166. package/dist/planning/__tests__/context-pack-status.test.d.ts.map +1 -0
  167. package/dist/planning/__tests__/context-pack-status.test.js +271 -0
  168. package/dist/planning/__tests__/context-pack-status.test.js.map +1 -0
  169. package/dist/planning/artifacts.d.ts +12 -1
  170. package/dist/planning/artifacts.d.ts.map +1 -1
  171. package/dist/planning/artifacts.js +32 -9
  172. package/dist/planning/artifacts.js.map +1 -1
  173. package/dist/planning/context-pack-status.d.ts +42 -0
  174. package/dist/planning/context-pack-status.d.ts.map +1 -0
  175. package/dist/planning/context-pack-status.js +479 -0
  176. package/dist/planning/context-pack-status.js.map +1 -0
  177. package/dist/runtime/__tests__/process-tree.test.d.ts +2 -0
  178. package/dist/runtime/__tests__/process-tree.test.d.ts.map +1 -0
  179. package/dist/runtime/__tests__/process-tree.test.js +107 -0
  180. package/dist/runtime/__tests__/process-tree.test.js.map +1 -0
  181. package/dist/runtime/process-tree.d.ts +28 -0
  182. package/dist/runtime/process-tree.d.ts.map +1 -0
  183. package/dist/runtime/process-tree.js +230 -0
  184. package/dist/runtime/process-tree.js.map +1 -0
  185. package/dist/scripts/__tests__/codex-native-hook.test.js +267 -2
  186. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  187. package/dist/scripts/__tests__/notify-state-io.test.d.ts +2 -0
  188. package/dist/scripts/__tests__/notify-state-io.test.d.ts.map +1 -0
  189. package/dist/scripts/__tests__/notify-state-io.test.js +40 -0
  190. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -0
  191. package/dist/scripts/codex-execution-surface.d.ts +1 -1
  192. package/dist/scripts/codex-execution-surface.d.ts.map +1 -1
  193. package/dist/scripts/codex-execution-surface.js.map +1 -1
  194. package/dist/scripts/codex-native-hook.d.ts +1 -1
  195. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  196. package/dist/scripts/codex-native-hook.js +141 -9
  197. package/dist/scripts/codex-native-hook.js.map +1 -1
  198. package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
  199. package/dist/scripts/notify-hook/managed-tmux.js +6 -9
  200. package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
  201. package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
  202. package/dist/scripts/notify-hook/process-runner.js +4 -1
  203. package/dist/scripts/notify-hook/process-runner.js.map +1 -1
  204. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  205. package/dist/scripts/notify-hook/state-io.js +4 -7
  206. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  207. package/dist/scripts/notify-hook.js +25 -3
  208. package/dist/scripts/notify-hook.js.map +1 -1
  209. package/dist/scripts/verify-native-agents.d.ts.map +1 -1
  210. package/dist/scripts/verify-native-agents.js +3 -1
  211. package/dist/scripts/verify-native-agents.js.map +1 -1
  212. package/dist/sidecar/__tests__/tmux.test.js +1 -1
  213. package/dist/sidecar/__tests__/tmux.test.js.map +1 -1
  214. package/dist/sidecar/tmux.js +1 -1
  215. package/dist/sidecar/tmux.js.map +1 -1
  216. package/dist/state/__tests__/operations.test.js +79 -0
  217. package/dist/state/__tests__/operations.test.js.map +1 -1
  218. package/dist/state/__tests__/skill-active.test.js +10 -18
  219. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  220. package/dist/state/__tests__/workflow-transition.test.js +45 -1
  221. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  222. package/dist/state/operations.d.ts.map +1 -1
  223. package/dist/state/operations.js +1 -20
  224. package/dist/state/operations.js.map +1 -1
  225. package/dist/state/skill-active.d.ts +1 -0
  226. package/dist/state/skill-active.d.ts.map +1 -1
  227. package/dist/state/skill-active.js +28 -18
  228. package/dist/state/skill-active.js.map +1 -1
  229. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  230. package/dist/state/workflow-transition-reconcile.js +3 -2
  231. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  232. package/dist/state/workflow-transition.js +2 -2
  233. package/dist/state/workflow-transition.js.map +1 -1
  234. package/dist/team/__tests__/approved-execution.test.js +96 -0
  235. package/dist/team/__tests__/approved-execution.test.js.map +1 -1
  236. package/dist/team/__tests__/followup-planner.test.js +16 -0
  237. package/dist/team/__tests__/followup-planner.test.js.map +1 -1
  238. package/dist/team/__tests__/model-contract.test.js +16 -0
  239. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  240. package/dist/team/__tests__/repo-aware-decomposition.test.js +20 -0
  241. package/dist/team/__tests__/repo-aware-decomposition.test.js.map +1 -1
  242. package/dist/team/__tests__/runtime-cli.test.js +16 -0
  243. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  244. package/dist/team/__tests__/runtime.test.js +209 -11
  245. package/dist/team/__tests__/runtime.test.js.map +1 -1
  246. package/dist/team/__tests__/scaling.test.js +110 -0
  247. package/dist/team/__tests__/scaling.test.js.map +1 -1
  248. package/dist/team/__tests__/tmux-session.test.js +9 -0
  249. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  250. package/dist/team/__tests__/worker-runtime-identity.test.js +6 -0
  251. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  252. package/dist/team/approved-execution.d.ts +13 -0
  253. package/dist/team/approved-execution.d.ts.map +1 -1
  254. package/dist/team/approved-execution.js +40 -22
  255. package/dist/team/approved-execution.js.map +1 -1
  256. package/dist/team/followup-planner.d.ts +1 -0
  257. package/dist/team/followup-planner.d.ts.map +1 -1
  258. package/dist/team/followup-planner.js +9 -9
  259. package/dist/team/followup-planner.js.map +1 -1
  260. package/dist/team/model-contract.d.ts +1 -1
  261. package/dist/team/model-contract.d.ts.map +1 -1
  262. package/dist/team/model-contract.js +4 -3
  263. package/dist/team/model-contract.js.map +1 -1
  264. package/dist/team/repo-aware-decomposition.d.ts +1 -0
  265. package/dist/team/repo-aware-decomposition.d.ts.map +1 -1
  266. package/dist/team/repo-aware-decomposition.js +5 -1
  267. package/dist/team/repo-aware-decomposition.js.map +1 -1
  268. package/dist/team/runtime-cli.d.ts +4 -0
  269. package/dist/team/runtime-cli.d.ts.map +1 -1
  270. package/dist/team/runtime-cli.js +14 -1
  271. package/dist/team/runtime-cli.js.map +1 -1
  272. package/dist/team/runtime.d.ts +1 -0
  273. package/dist/team/runtime.d.ts.map +1 -1
  274. package/dist/team/runtime.js +46 -16
  275. package/dist/team/runtime.js.map +1 -1
  276. package/dist/team/scaling.d.ts.map +1 -1
  277. package/dist/team/scaling.js +13 -6
  278. package/dist/team/scaling.js.map +1 -1
  279. package/dist/team/tmux-session.d.ts.map +1 -1
  280. package/dist/team/tmux-session.js +7 -0
  281. package/dist/team/tmux-session.js.map +1 -1
  282. package/dist/ultragoal/__tests__/artifacts.test.js +129 -4
  283. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  284. package/dist/ultragoal/__tests__/docs-contract.test.d.ts +2 -0
  285. package/dist/ultragoal/__tests__/docs-contract.test.d.ts.map +1 -0
  286. package/dist/ultragoal/__tests__/docs-contract.test.js +31 -0
  287. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -0
  288. package/dist/ultragoal/artifacts.d.ts +6 -2
  289. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  290. package/dist/ultragoal/artifacts.js +108 -4
  291. package/dist/ultragoal/artifacts.js.map +1 -1
  292. package/dist/utils/paths.d.ts +3 -1
  293. package/dist/utils/paths.d.ts.map +1 -1
  294. package/dist/utils/paths.js +6 -2
  295. package/dist/utils/paths.js.map +1 -1
  296. package/dist/verification/__tests__/ci-rust-gates.test.js +44 -14
  297. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  298. package/dist/wiki/__tests__/ingest.test.js +35 -1
  299. package/dist/wiki/__tests__/ingest.test.js.map +1 -1
  300. package/dist/wiki/__tests__/lint.test.js +14 -1
  301. package/dist/wiki/__tests__/lint.test.js.map +1 -1
  302. package/dist/wiki/__tests__/query.test.js +28 -3
  303. package/dist/wiki/__tests__/query.test.js.map +1 -1
  304. package/dist/wiki/__tests__/session-hooks.test.js +30 -2
  305. package/dist/wiki/__tests__/session-hooks.test.js.map +1 -1
  306. package/dist/wiki/__tests__/storage.test.js +62 -22
  307. package/dist/wiki/__tests__/storage.test.js.map +1 -1
  308. package/dist/wiki/index.d.ts +2 -2
  309. package/dist/wiki/index.d.ts.map +1 -1
  310. package/dist/wiki/index.js +2 -2
  311. package/dist/wiki/index.js.map +1 -1
  312. package/dist/wiki/ingest.js +2 -2
  313. package/dist/wiki/ingest.js.map +1 -1
  314. package/dist/wiki/lifecycle.d.ts +5 -0
  315. package/dist/wiki/lifecycle.d.ts.map +1 -1
  316. package/dist/wiki/lifecycle.js +31 -4
  317. package/dist/wiki/lifecycle.js.map +1 -1
  318. package/dist/wiki/lint.d.ts.map +1 -1
  319. package/dist/wiki/lint.js +12 -8
  320. package/dist/wiki/lint.js.map +1 -1
  321. package/dist/wiki/query.d.ts.map +1 -1
  322. package/dist/wiki/query.js +3 -2
  323. package/dist/wiki/query.js.map +1 -1
  324. package/dist/wiki/storage.d.ts +4 -0
  325. package/dist/wiki/storage.d.ts.map +1 -1
  326. package/dist/wiki/storage.js +54 -18
  327. package/dist/wiki/storage.js.map +1 -1
  328. package/package.json +1 -1
  329. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  330. package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +9 -0
  331. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +25 -2
  332. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +1 -1
  333. package/plugins/oh-my-codex/skills/plan/SKILL.md +7 -4
  334. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +13 -3
  335. package/plugins/oh-my-codex/skills/team/SKILL.md +2 -2
  336. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +11 -7
  337. package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +8 -0
  338. package/plugins/oh-my-codex/skills/wiki/SKILL.md +5 -5
  339. package/prompts/planner.md +1 -1
  340. package/skills/ai-slop-cleaner/SKILL.md +9 -0
  341. package/skills/deep-interview/SKILL.md +25 -2
  342. package/skills/omx-setup/SKILL.md +1 -1
  343. package/skills/plan/SKILL.md +7 -4
  344. package/skills/ralplan/SKILL.md +13 -3
  345. package/skills/team/SKILL.md +2 -2
  346. package/skills/ultragoal/SKILL.md +11 -7
  347. package/skills/visual-ralph/SKILL.md +8 -0
  348. package/skills/wiki/SKILL.md +5 -5
  349. package/src/scripts/__tests__/codex-native-hook.test.ts +302 -2
  350. package/src/scripts/__tests__/notify-state-io.test.ts +73 -0
  351. package/src/scripts/codex-execution-surface.ts +2 -0
  352. package/src/scripts/codex-native-hook.ts +163 -16
  353. package/src/scripts/notify-hook/managed-tmux.ts +6 -7
  354. package/src/scripts/notify-hook/process-runner.ts +4 -1
  355. package/src/scripts/notify-hook/state-io.ts +5 -7
  356. package/src/scripts/notify-hook.ts +26 -3
  357. package/src/scripts/verify-native-agents.ts +3 -1
@@ -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, resolveEffectiveLeaderLaunchPolicyOverride, resolveEnvLaunchPolicyOverride, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupScopeArg, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, shouldAutoIsolateMadmaxLaunch, createMadmaxIsolatedRoot, prepareCodexHomeForLaunch, runtimeCodexHomePath, 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, shouldAutoIsolateMadmaxLaunch, createMadmaxIsolatedRoot, resolveOmxRootForLaunch, resolveDisposableWorktreeOmxRootForLaunch, prepareCodexHomeForLaunch, runtimeCodexHomePath, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript, buildDetachedWindowsBootstrapScript, acquireTmuxExtendedKeysLease, resolveNativeSessionName, releaseTmuxExtendedKeysLease, withTmuxExtendedKeys, CODEX_SQLITE_HOME_ENV, } 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";
@@ -57,6 +57,44 @@ describe("madmax state isolation", () => {
57
57
  }
58
58
  });
59
59
  });
60
+ describe("resolveOmxRootForLaunch", () => {
61
+ it("preserves POSIX absolute OMX_ROOT", () => {
62
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: "/var/tmp/omx" }), "/var/tmp/omx");
63
+ });
64
+ it("preserves Windows drive-letter absolute OMX_ROOT", () => {
65
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: "C:\\Users\\me\\omx" }), "C:\\Users\\me\\omx");
66
+ });
67
+ it("preserves Windows drive-letter absolute OMX_STATE_ROOT", () => {
68
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_STATE_ROOT: "D:\\omx-state" }), "D:\\omx-state");
69
+ });
70
+ it("preserves UNC absolute OMX_ROOT", () => {
71
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: "\\\\server\\share\\omx" }), "\\\\server\\share\\omx");
72
+ });
73
+ it("joins relative OMX_ROOT to cwd", () => {
74
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: "relative/omx" }), join("/repo", "relative/omx"));
75
+ });
76
+ it("returns undefined for blank OMX_ROOT and OMX_STATE_ROOT", () => {
77
+ assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: " ", OMX_STATE_ROOT: "" }), undefined);
78
+ });
79
+ it("prefers OMX_ROOT over OMX_STATE_ROOT", () => {
80
+ assert.equal(resolveOmxRootForLaunch("/repo", {
81
+ OMX_ROOT: "C:\\Users\\me\\root",
82
+ OMX_STATE_ROOT: "/state-root",
83
+ }), "C:\\Users\\me\\root");
84
+ });
85
+ });
86
+ describe("disposable worktree state root resolution", () => {
87
+ it("uses the source repo root for launch worktrees when no explicit root is set", () => {
88
+ assert.equal(resolveDisposableWorktreeOmxRootForLaunch({ enabled: true, repoRoot: "/repo" }, {}), "/repo");
89
+ });
90
+ it("preserves explicit OMX_ROOT and OMX_STATE_ROOT precedence", () => {
91
+ assert.equal(resolveDisposableWorktreeOmxRootForLaunch({ enabled: true, repoRoot: "/repo" }, { OMX_ROOT: "/explicit" }), undefined);
92
+ assert.equal(resolveDisposableWorktreeOmxRootForLaunch({ enabled: true, repoRoot: "/repo" }, { OMX_STATE_ROOT: "/state-root" }), undefined);
93
+ });
94
+ it("does not affect non-worktree launches", () => {
95
+ assert.equal(resolveDisposableWorktreeOmxRootForLaunch({ enabled: false }, {}), undefined);
96
+ });
97
+ });
60
98
  describe("normalizeCodexLaunchArgs", () => {
61
99
  it("maps --madmax to codex bypass flag", () => {
62
100
  assert.deepEqual(normalizeCodexLaunchArgs(["--madmax"]), [
@@ -377,14 +415,14 @@ describe("cleanupPostLaunchModeStateFiles", () => {
377
415
  const partialState = '{\n "active": true,\n "mode": "ralph",\n';
378
416
  const warnings = [];
379
417
  await mkdir(sessionStateDir, { recursive: true });
380
- await writeFile(join(stateDir, "autopilot-state.json"), JSON.stringify({ active: true, mode: "autopilot" }, null, 2), "utf-8");
381
- await writeFile(join(stateDir, "deep-interview-state.json"), "", "utf-8");
418
+ await writeFile(join(sessionStateDir, "autopilot-state.json"), JSON.stringify({ active: true, mode: "autopilot" }, null, 2), "utf-8");
419
+ await writeFile(join(sessionStateDir, "deep-interview-state.json"), "", "utf-8");
382
420
  await writeFile(join(sessionStateDir, "ralph-state.json"), partialState, "utf-8");
383
421
  await cleanupPostLaunchModeStateFiles(wd, sessionId, {
384
422
  writeWarn: (line) => warnings.push(line),
385
423
  });
386
- const autopilot = JSON.parse(await readFile(join(stateDir, "autopilot-state.json"), "utf-8"));
387
- const deepInterview = JSON.parse(await readFile(join(stateDir, "deep-interview-state.json"), "utf-8"));
424
+ const autopilot = JSON.parse(await readFile(join(sessionStateDir, "autopilot-state.json"), "utf-8"));
425
+ const deepInterview = JSON.parse(await readFile(join(sessionStateDir, "deep-interview-state.json"), "utf-8"));
388
426
  const ralph = JSON.parse(await readFile(join(sessionStateDir, "ralph-state.json"), "utf-8"));
389
427
  assert.equal(autopilot.active, false);
390
428
  assert.equal(typeof autopilot.completed_at, "string");
@@ -412,16 +450,37 @@ describe("cleanupPostLaunchModeStateFiles", () => {
412
450
  }
413
451
  assert.deepEqual(warnings, []);
414
452
  });
453
+ it("does not cancel root mode state during session-scoped postLaunch cleanup", async () => {
454
+ const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-root-preserve-"));
455
+ const sessionId = "sess-postlaunch-root-preserve";
456
+ const stateDir = join(wd, ".omx", "state");
457
+ const sessionStateDir = join(stateDir, "sessions", sessionId);
458
+ await mkdir(sessionStateDir, { recursive: true });
459
+ await writeFile(join(stateDir, "ralph-state.json"), JSON.stringify({ active: true, mode: "ralph", current_phase: "executing" }, null, 2), "utf-8");
460
+ await writeFile(join(sessionStateDir, "ralplan-state.json"), JSON.stringify({ active: true, mode: "ralplan", current_phase: "planning" }, null, 2), "utf-8");
461
+ try {
462
+ await cleanupPostLaunchModeStateFiles(wd, sessionId);
463
+ const rootRalph = JSON.parse(await readFile(join(stateDir, "ralph-state.json"), "utf-8"));
464
+ const sessionRalplan = JSON.parse(await readFile(join(sessionStateDir, "ralplan-state.json"), "utf-8"));
465
+ assert.equal(rootRalph.active, true);
466
+ assert.equal(sessionRalplan.active, false);
467
+ assert.equal(sessionRalplan.current_phase, "cancelled");
468
+ }
469
+ finally {
470
+ await rm(wd, { recursive: true, force: true });
471
+ }
472
+ });
415
473
  it("retries a transient parse failure before cancelling the rewritten mode state", async () => {
416
474
  const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-mode-retry-"));
417
475
  const sessionId = "sess-postlaunch-retry";
418
476
  const stateDir = join(wd, ".omx", "state");
419
- const statePath = join(stateDir, "ralph-state.json");
477
+ const sessionStateDir = join(stateDir, "sessions", sessionId);
478
+ const statePath = join(sessionStateDir, "ralph-state.json");
420
479
  const writes = [];
421
480
  const validState = JSON.stringify({ active: true, mode: "ralph" }, null, 2);
422
481
  let reads = 0;
423
- await mkdir(stateDir, { recursive: true });
424
- const mockReaddir = (async (dir, _options) => (String(dir) === stateDir ? ["ralph-state.json"] : []));
482
+ await mkdir(sessionStateDir, { recursive: true });
483
+ const mockReaddir = (async (dir, _options) => (String(dir) === sessionStateDir ? ["ralph-state.json"] : []));
425
484
  const mockReadFile = (async (path, _options) => {
426
485
  assert.equal(String(path), statePath);
427
486
  reads += 1;
@@ -451,15 +510,16 @@ describe("cleanupPostLaunchModeStateFiles", () => {
451
510
  const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-mode-malformed-"));
452
511
  const sessionId = "sess-postlaunch-malformed";
453
512
  const stateDir = join(wd, ".omx", "state");
513
+ const sessionStateDir = join(stateDir, "sessions", sessionId);
454
514
  const warnings = [];
455
515
  const malformedState = '{\n "active": true,\n}\n';
456
- await mkdir(stateDir, { recursive: true });
457
- await writeFile(join(stateDir, "ralph-state.json"), malformedState, "utf-8");
458
- await writeFile(join(stateDir, "ultrawork-state.json"), JSON.stringify({ active: true, mode: "ultrawork" }, null, 2), "utf-8");
516
+ await mkdir(sessionStateDir, { recursive: true });
517
+ await writeFile(join(sessionStateDir, "ralph-state.json"), malformedState, "utf-8");
518
+ await writeFile(join(sessionStateDir, "ultrawork-state.json"), JSON.stringify({ active: true, mode: "ultrawork" }, null, 2), "utf-8");
459
519
  await cleanupPostLaunchModeStateFiles(wd, sessionId, {
460
520
  writeWarn: (line) => warnings.push(line),
461
521
  });
462
- const ultrawork = JSON.parse(await readFile(join(stateDir, "ultrawork-state.json"), "utf-8"));
522
+ const ultrawork = JSON.parse(await readFile(join(sessionStateDir, "ultrawork-state.json"), "utf-8"));
463
523
  assert.equal(ultrawork.active, false);
464
524
  assert.equal(typeof ultrawork.completed_at, "string");
465
525
  const canonicalPath = join(stateDir, "skill-active-state.json");
@@ -468,10 +528,78 @@ describe("cleanupPostLaunchModeStateFiles", () => {
468
528
  assert.equal(canonical.active, false);
469
529
  assert.deepEqual(canonical.active_skills, []);
470
530
  }
471
- assert.equal(await readFile(join(stateDir, "ralph-state.json"), "utf-8"), malformedState);
531
+ assert.equal(await readFile(join(sessionStateDir, "ralph-state.json"), "utf-8"), malformedState);
472
532
  assert.equal(warnings.length, 1);
473
533
  assert.match(warnings[0] ?? "", /skipped malformed mode state .*ralph-state\.json/);
474
534
  });
535
+ it("reconciles root skill-active entries for the finished terminal session", async () => {
536
+ const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-root-skill-active-"));
537
+ const sessionId = "sess-terminal-autopilot";
538
+ const otherSessionId = "sess-other";
539
+ const stateDir = join(wd, ".omx", "state");
540
+ const sessionStateDir = join(stateDir, "sessions", sessionId);
541
+ try {
542
+ await mkdir(sessionStateDir, { recursive: true });
543
+ await writeFile(join(stateDir, "skill-active-state.json"), JSON.stringify({
544
+ version: 1,
545
+ active: true,
546
+ skill: "autopilot",
547
+ phase: "ralph",
548
+ session_id: sessionId,
549
+ initialized_state_path: `.omx/state/sessions/${sessionId}/autopilot-state.json`,
550
+ active_skills: [
551
+ { skill: "autopilot", phase: "ralph", active: true, session_id: sessionId },
552
+ { skill: "team", phase: "running", active: true, session_id: otherSessionId },
553
+ ],
554
+ }, null, 2), "utf-8");
555
+ await cleanupPostLaunchModeStateFiles(wd, sessionId);
556
+ const rootCanonical = JSON.parse(await readFile(join(stateDir, "skill-active-state.json"), "utf-8"));
557
+ assert.equal(rootCanonical.active, true);
558
+ assert.deepEqual(rootCanonical.active_skills, [
559
+ { skill: "team", phase: "running", active: true, session_id: otherSessionId },
560
+ ]);
561
+ }
562
+ finally {
563
+ await rm(wd, { recursive: true, force: true });
564
+ }
565
+ });
566
+ it("preserves other-session active skills when session mode cleanup syncs before root scrub", async () => {
567
+ const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-mode-root-skill-active-"));
568
+ const sessionId = "sess-terminal-autopilot";
569
+ const otherSessionId = "sess-other-team";
570
+ const stateDir = join(wd, ".omx", "state");
571
+ const sessionStateDir = join(stateDir, "sessions", sessionId);
572
+ try {
573
+ await mkdir(sessionStateDir, { recursive: true });
574
+ await writeFile(join(stateDir, "skill-active-state.json"), JSON.stringify({
575
+ version: 1,
576
+ active: true,
577
+ skill: "autopilot",
578
+ phase: "ralph",
579
+ session_id: sessionId,
580
+ initialized_state_path: `.omx/state/sessions/${sessionId}/autopilot-state.json`,
581
+ active_skills: [
582
+ { skill: "autopilot", phase: "ralph", active: true, session_id: sessionId },
583
+ { skill: "team", phase: "running", active: true, session_id: otherSessionId },
584
+ ],
585
+ }, null, 2), "utf-8");
586
+ await writeFile(join(sessionStateDir, "autopilot-state.json"), JSON.stringify({ active: true, mode: "autopilot", current_phase: "ralph" }, null, 2), "utf-8");
587
+ await cleanupPostLaunchModeStateFiles(wd, sessionId);
588
+ const autopilotState = JSON.parse(await readFile(join(sessionStateDir, "autopilot-state.json"), "utf-8"));
589
+ assert.equal(autopilotState.active, false);
590
+ assert.equal(autopilotState.current_phase, "cancelled");
591
+ const rootCanonical = JSON.parse(await readFile(join(stateDir, "skill-active-state.json"), "utf-8"));
592
+ assert.equal(rootCanonical.active, true);
593
+ assert.equal(rootCanonical.skill, "team");
594
+ assert.equal(rootCanonical.phase, "running");
595
+ assert.deepEqual(rootCanonical.active_skills, [
596
+ { skill: "team", phase: "running", active: true, session_id: otherSessionId },
597
+ ]);
598
+ }
599
+ finally {
600
+ await rm(wd, { recursive: true, force: true });
601
+ }
602
+ });
475
603
  it("clears canonical skill-active entries during cleanup and hides them from HUD/overlay readers", async () => {
476
604
  const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-skill-active-cleanup-"));
477
605
  const sessionId = "sess-skill-active-cleanup";
@@ -800,13 +928,17 @@ describe("resolveCliInvocation", () => {
800
928
  it("advertises the explicit update command in top-level help", () => {
801
929
  assert.match(HELP, /omx update\s+Check npm now, update the global install immediately, then refresh setup/);
802
930
  });
803
- it("advertises direct launch policy controls in top-level help", () => {
931
+ it("advertises concise launch policy controls in top-level help", () => {
804
932
  assert.match(HELP, /--direct\s+Launch the interactive leader directly/);
805
- assert.match(HELP, /OMX_LAUNCH_POLICY=direct\|tmux\|detached-tmux\|auto/);
806
- assert.match(HELP, /unset OMX_LAUNCH_POLICY/);
807
- assert.match(HELP, /omx --direct --yolo/);
808
- assert.match(HELP, /OMX_LAUNCH_POLICY=direct omx --tmux --yolo/);
933
+ assert.match(HELP, /OMX_LAUNCH_POLICY=auto[\s\S]*Use the default policy/);
934
+ assert.match(HELP, /OMX_LAUNCH_POLICY=direct[\s\S]*Run without OMX tmux\/HUD management/);
935
+ assert.match(HELP, /OMX_LAUNCH_POLICY=tmux[\s\S]*Force OMX-managed detached tmux launch/);
936
+ assert.match(HELP, /OMX_LAUNCH_POLICY=detached-tmux[\s\S]*Force OMX-managed detached tmux launch/);
937
+ assert.match(HELP, /CLI policy flags \(--direct\/--tmux\) override OMX_LAUNCH_POLICY/);
938
+ assert.match(HELP, /Unset or empty OMX_LAUNCH_POLICY returns to auto\/default behavior/);
809
939
  assert.match(HELP, /Config files are intentionally not used/);
940
+ assert.doesNotMatch(HELP, /OMX_LAUNCH_POLICY=direct\|tmux\|detached-tmux\|auto/);
941
+ assert.doesNotMatch(HELP, /OMX_LAUNCH_POLICY=direct omx --tmux --yolo/);
810
942
  });
811
943
  });
812
944
  describe("resolveSetupInstallModeArg", () => {
@@ -957,14 +1089,21 @@ describe("project launch scope helpers", () => {
957
1089
  ].join("\n");
958
1090
  await writeFile(configPath, originalConfig);
959
1091
  await writeFile(join(projectCodexHome, "agents", "planner.toml"), 'name = "planner"\n');
1092
+ await writeFile(join(projectCodexHome, "state_5.sqlite"), "state db placeholder");
1093
+ await writeFile(join(projectCodexHome, "state_5.sqlite-wal"), "state db wal placeholder");
1094
+ await writeFile(join(projectCodexHome, "logs_2.sqlite-shm"), "logs db shm placeholder");
960
1095
  const beforeStat = await stat(configPath);
961
1096
  const prepared = await prepareCodexHomeForLaunch(wd, "session-2033", {});
962
1097
  const runtimeCodexHome = runtimeCodexHomePath(wd, "session-2033");
963
1098
  assert.equal(prepared.codexHomeOverride, runtimeCodexHome);
1099
+ assert.equal(prepared.sqliteHomeOverride, projectCodexHome);
964
1100
  assert.equal(prepared.projectLocalCodexHomeForCleanup, projectCodexHome);
965
1101
  assert.equal(prepared.runtimeCodexHomeForCleanup, runtimeCodexHome);
966
1102
  assert.equal(await readFile(join(runtimeCodexHome, "config.toml"), "utf-8"), originalConfig);
967
1103
  assert.equal(await readFile(join(runtimeCodexHome, "agents", "planner.toml"), "utf-8"), 'name = "planner"\n');
1104
+ assert.equal(existsSync(join(runtimeCodexHome, "state_5.sqlite")), false);
1105
+ assert.equal(existsSync(join(runtimeCodexHome, "state_5.sqlite-wal")), false);
1106
+ assert.equal(existsSync(join(runtimeCodexHome, "logs_2.sqlite-shm")), false);
968
1107
  await writeFile(join(runtimeCodexHome, "config.toml"), `${originalConfig}\n[tui.model_availability_nux]\n"gpt-5.5" = 1\n`);
969
1108
  assert.equal(await readFile(configPath, "utf-8"), originalConfig);
970
1109
  assert.doesNotMatch(await readFile(configPath, "utf-8"), /model_availability_nux/);
@@ -1013,6 +1152,7 @@ describe("project launch scope helpers", () => {
1013
1152
  CODEX_HOME: "/tmp/explicit-codex-home",
1014
1153
  });
1015
1154
  assert.equal(prepared.codexHomeOverride, "/tmp/explicit-codex-home");
1155
+ assert.equal(prepared.sqliteHomeOverride, undefined);
1016
1156
  assert.equal(prepared.projectLocalCodexHomeForCleanup, undefined);
1017
1157
  assert.equal(prepared.runtimeCodexHomeForCleanup, undefined);
1018
1158
  }
@@ -1020,6 +1160,23 @@ describe("project launch scope helpers", () => {
1020
1160
  await rm(wd, { recursive: true, force: true });
1021
1161
  }
1022
1162
  });
1163
+ it("respects explicit CODEX_SQLITE_HOME for project-scope launches", async () => {
1164
+ const wd = await mkdtemp(join(tmpdir(), "omx-launch-sqlite-home-"));
1165
+ try {
1166
+ await mkdir(join(wd, ".omx"), { recursive: true });
1167
+ await mkdir(join(wd, ".codex"), { recursive: true });
1168
+ await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "project" }));
1169
+ await writeFile(join(wd, ".codex", "config.toml"), 'model = "gpt-5.5"\n');
1170
+ const prepared = await prepareCodexHomeForLaunch(wd, "session-explicit-sqlite", {
1171
+ [CODEX_SQLITE_HOME_ENV]: "/tmp/explicit-sqlite-home",
1172
+ });
1173
+ assert.equal(prepared.codexHomeOverride, runtimeCodexHomePath(wd, "session-explicit-sqlite"));
1174
+ assert.equal(prepared.sqliteHomeOverride, undefined);
1175
+ }
1176
+ finally {
1177
+ await rm(wd, { recursive: true, force: true });
1178
+ }
1179
+ });
1023
1180
  it("keeps explicit CODEX_HOME override from env", async () => {
1024
1181
  const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
1025
1182
  try {
@@ -1278,6 +1435,13 @@ describe("detached tmux new-session sequencing", () => {
1278
1435
  assert.equal(newSession.args.includes("-e") &&
1279
1436
  newSession.args.some((arg) => arg === "CODEX_HOME=/tmp/project/.codex"), true);
1280
1437
  });
1438
+ it("buildDetachedSessionBootstrapSteps forwards CODEX_SQLITE_HOME override to detached tmux session", () => {
1439
+ const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, "/tmp/project/.omx/runtime/codex-home/session-1", null, false, "sess-detached-managed", undefined, undefined, undefined, {}, "/tmp/project/.codex");
1440
+ const newSession = steps.find((step) => step.name === "new-session");
1441
+ assert.ok(newSession);
1442
+ assert.equal(newSession.args.includes("-e") &&
1443
+ newSession.args.some((arg) => arg === `${CODEX_SQLITE_HOME_ENV}=/tmp/project/.codex`), true);
1444
+ });
1281
1445
  it("buildDetachedSessionBootstrapSteps forwards OMX_ROOT override to detached tmux session", () => {
1282
1446
  const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, undefined, null, false, "sess-detached-managed", undefined, undefined, "/tmp/omx-root");
1283
1447
  const newSession = steps.find((step) => step.name === "new-session");