oh-my-codex 0.18.13 → 0.18.15

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 (360) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +1 -1
  3. package/README.md +41 -18
  4. package/dist/agents/__tests__/native-config.test.js +62 -0
  5. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  6. package/dist/agents/native-config.d.ts.map +1 -1
  7. package/dist/agents/native-config.js +15 -2
  8. package/dist/agents/native-config.js.map +1 -1
  9. package/dist/autopilot/__tests__/fsm.test.js +7 -0
  10. package/dist/autopilot/__tests__/fsm.test.js.map +1 -1
  11. package/dist/autopilot/__tests__/planner-routing.test.d.ts +2 -0
  12. package/dist/autopilot/__tests__/planner-routing.test.d.ts.map +1 -0
  13. package/dist/autopilot/__tests__/planner-routing.test.js +74 -0
  14. package/dist/autopilot/__tests__/planner-routing.test.js.map +1 -0
  15. package/dist/autopilot/__tests__/ralplan-gate.test.js +315 -0
  16. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
  17. package/dist/autopilot/completion-gate.js +1 -1
  18. package/dist/autopilot/completion-gate.js.map +1 -1
  19. package/dist/autopilot/fsm.d.ts +2 -2
  20. package/dist/autopilot/fsm.d.ts.map +1 -1
  21. package/dist/autopilot/fsm.js +3 -0
  22. package/dist/autopilot/fsm.js.map +1 -1
  23. package/dist/autopilot/planner-routing.d.ts +21 -0
  24. package/dist/autopilot/planner-routing.d.ts.map +1 -0
  25. package/dist/autopilot/planner-routing.js +59 -0
  26. package/dist/autopilot/planner-routing.js.map +1 -0
  27. package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
  28. package/dist/autopilot/ralplan-gate.js +30 -0
  29. package/dist/autopilot/ralplan-gate.js.map +1 -1
  30. package/dist/autoresearch/goal.d.ts.map +1 -1
  31. package/dist/autoresearch/goal.js +10 -1
  32. package/dist/autoresearch/goal.js.map +1 -1
  33. package/dist/cli/__tests__/autoresearch-goal.test.js +33 -0
  34. package/dist/cli/__tests__/autoresearch-goal.test.js.map +1 -1
  35. package/dist/cli/__tests__/autoresearch-guided.test.js +3 -0
  36. package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
  37. package/dist/cli/__tests__/codex-plugin-layout.test.js +30 -0
  38. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  39. package/dist/cli/__tests__/doctor-artifact-ownership.test.d.ts +2 -0
  40. package/dist/cli/__tests__/doctor-artifact-ownership.test.d.ts.map +1 -0
  41. package/dist/cli/__tests__/doctor-artifact-ownership.test.js +158 -0
  42. package/dist/cli/__tests__/doctor-artifact-ownership.test.js.map +1 -0
  43. package/dist/cli/__tests__/doctor-explore-deprecated.test.d.ts +2 -0
  44. package/dist/cli/__tests__/doctor-explore-deprecated.test.d.ts.map +1 -0
  45. package/dist/cli/__tests__/doctor-explore-deprecated.test.js +33 -0
  46. package/dist/cli/__tests__/doctor-explore-deprecated.test.js.map +1 -0
  47. package/dist/cli/__tests__/doctor-spark-routing.test.js +13 -0
  48. package/dist/cli/__tests__/doctor-spark-routing.test.js.map +1 -1
  49. package/dist/cli/__tests__/doctor-warning-copy.test.js +132 -2
  50. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  51. package/dist/cli/__tests__/index.test.js +5 -0
  52. package/dist/cli/__tests__/index.test.js.map +1 -1
  53. package/dist/cli/__tests__/mcp-parity.test.js +40 -0
  54. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  55. package/dist/cli/__tests__/nested-help-routing.test.js +4 -0
  56. package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
  57. package/dist/cli/__tests__/package-bin-contract.test.js +7 -1
  58. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  59. package/dist/cli/__tests__/performance-goal.test.js +22 -0
  60. package/dist/cli/__tests__/performance-goal.test.js.map +1 -1
  61. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.d.ts +2 -0
  62. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.d.ts.map +1 -0
  63. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js +64 -0
  64. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js.map +1 -0
  65. package/dist/cli/__tests__/resume.test.js +96 -0
  66. package/dist/cli/__tests__/resume.test.js.map +1 -1
  67. package/dist/cli/__tests__/session-scoped-runtime.test.js +162 -0
  68. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  69. package/dist/cli/__tests__/session-search.test.js +36 -0
  70. package/dist/cli/__tests__/session-search.test.js.map +1 -1
  71. package/dist/cli/__tests__/setup-agents-overwrite.test.js +70 -1
  72. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  73. package/dist/cli/__tests__/setup-install-mode.test.js +33 -0
  74. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  75. package/dist/cli/__tests__/team.test.js +17 -3
  76. package/dist/cli/__tests__/team.test.js.map +1 -1
  77. package/dist/cli/__tests__/ultragoal.test.js +37 -0
  78. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  79. package/dist/cli/__tests__/update.test.js +81 -2
  80. package/dist/cli/__tests__/update.test.js.map +1 -1
  81. package/dist/cli/__tests__/url.test.d.ts +2 -0
  82. package/dist/cli/__tests__/url.test.d.ts.map +1 -0
  83. package/dist/cli/__tests__/url.test.js +82 -0
  84. package/dist/cli/__tests__/url.test.js.map +1 -0
  85. package/dist/cli/autoresearch-goal.d.ts.map +1 -1
  86. package/dist/cli/autoresearch-goal.js +2 -1
  87. package/dist/cli/autoresearch-goal.js.map +1 -1
  88. package/dist/cli/autoresearch-intake.d.ts.map +1 -1
  89. package/dist/cli/autoresearch-intake.js +2 -0
  90. package/dist/cli/autoresearch-intake.js.map +1 -1
  91. package/dist/cli/doctor.d.ts +39 -1
  92. package/dist/cli/doctor.d.ts.map +1 -1
  93. package/dist/cli/doctor.js +460 -40
  94. package/dist/cli/doctor.js.map +1 -1
  95. package/dist/cli/index.d.ts +2 -2
  96. package/dist/cli/index.d.ts.map +1 -1
  97. package/dist/cli/index.js +71 -4
  98. package/dist/cli/index.js.map +1 -1
  99. package/dist/cli/performance-goal.d.ts.map +1 -1
  100. package/dist/cli/performance-goal.js +4 -2
  101. package/dist/cli/performance-goal.js.map +1 -1
  102. package/dist/cli/plugin-marketplace.d.ts +1 -0
  103. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  104. package/dist/cli/plugin-marketplace.js +88 -67
  105. package/dist/cli/plugin-marketplace.js.map +1 -1
  106. package/dist/cli/project-runtime-codex-homes.d.ts +2 -0
  107. package/dist/cli/project-runtime-codex-homes.d.ts.map +1 -1
  108. package/dist/cli/project-runtime-codex-homes.js +112 -5
  109. package/dist/cli/project-runtime-codex-homes.js.map +1 -1
  110. package/dist/cli/setup.d.ts.map +1 -1
  111. package/dist/cli/setup.js +15 -6
  112. package/dist/cli/setup.js.map +1 -1
  113. package/dist/cli/ultragoal.d.ts.map +1 -1
  114. package/dist/cli/ultragoal.js +5 -1
  115. package/dist/cli/ultragoal.js.map +1 -1
  116. package/dist/cli/update.d.ts.map +1 -1
  117. package/dist/cli/update.js +23 -4
  118. package/dist/cli/update.js.map +1 -1
  119. package/dist/cli/url.d.ts +8 -0
  120. package/dist/cli/url.d.ts.map +1 -0
  121. package/dist/cli/url.js +69 -0
  122. package/dist/cli/url.js.map +1 -0
  123. package/dist/config/__tests__/codex-hooks.test.js +20 -4
  124. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  125. package/dist/config/__tests__/models.test.js +21 -1
  126. package/dist/config/__tests__/models.test.js.map +1 -1
  127. package/dist/config/codex-hooks.d.ts.map +1 -1
  128. package/dist/config/codex-hooks.js +1 -4
  129. package/dist/config/codex-hooks.js.map +1 -1
  130. package/dist/config/models.d.ts +5 -0
  131. package/dist/config/models.d.ts.map +1 -1
  132. package/dist/config/models.js +23 -0
  133. package/dist/config/models.js.map +1 -1
  134. package/dist/goal-workflows/codex-goal-snapshot.d.ts +2 -0
  135. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  136. package/dist/goal-workflows/codex-goal-snapshot.js +10 -0
  137. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  138. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +7 -0
  139. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  140. package/dist/hooks/__tests__/keyword-detector.test.js +46 -0
  141. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  142. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +100 -0
  143. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  144. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +75 -0
  145. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  146. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +225 -0
  147. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  148. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +75 -0
  149. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  150. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +563 -0
  151. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  152. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +187 -12
  153. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  154. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +225 -0
  155. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  156. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
  157. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
  158. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +75 -0
  159. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  160. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  161. package/dist/hooks/keyword-detector.js +4 -0
  162. package/dist/hooks/keyword-detector.js.map +1 -1
  163. package/dist/hud/__tests__/reconcile.test.js +137 -2
  164. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  165. package/dist/hud/__tests__/state.test.js +107 -0
  166. package/dist/hud/__tests__/state.test.js.map +1 -1
  167. package/dist/hud/__tests__/tmux.test.js +17 -0
  168. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  169. package/dist/hud/reconcile.d.ts.map +1 -1
  170. package/dist/hud/reconcile.js +21 -7
  171. package/dist/hud/reconcile.js.map +1 -1
  172. package/dist/hud/render.d.ts.map +1 -1
  173. package/dist/hud/render.js +9 -0
  174. package/dist/hud/render.js.map +1 -1
  175. package/dist/hud/state.d.ts.map +1 -1
  176. package/dist/hud/state.js +43 -5
  177. package/dist/hud/state.js.map +1 -1
  178. package/dist/hud/types.d.ts +6 -0
  179. package/dist/hud/types.d.ts.map +1 -1
  180. package/dist/hud/types.js.map +1 -1
  181. package/dist/index.d.ts +1 -0
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +1 -0
  184. package/dist/index.js.map +1 -1
  185. package/dist/mcp/__tests__/bootstrap.test.js +24 -1
  186. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
  187. package/dist/mcp/__tests__/state-paths.test.js +53 -0
  188. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  189. package/dist/mcp/bootstrap.d.ts +2 -0
  190. package/dist/mcp/bootstrap.d.ts.map +1 -1
  191. package/dist/mcp/bootstrap.js +32 -6
  192. package/dist/mcp/bootstrap.js.map +1 -1
  193. package/dist/mcp/state-paths.d.ts.map +1 -1
  194. package/dist/mcp/state-paths.js +11 -5
  195. package/dist/mcp/state-paths.js.map +1 -1
  196. package/dist/modes/__tests__/base-autopilot-gates.test.js +48 -0
  197. package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
  198. package/dist/modes/base.d.ts.map +1 -1
  199. package/dist/modes/base.js +1 -0
  200. package/dist/modes/base.js.map +1 -1
  201. package/dist/notifications/__tests__/http-client.test.js +9 -0
  202. package/dist/notifications/__tests__/http-client.test.js.map +1 -1
  203. package/dist/notifications/http-client.js +1 -1
  204. package/dist/notifications/http-client.js.map +1 -1
  205. package/dist/performance-goal/artifacts.d.ts.map +1 -1
  206. package/dist/performance-goal/artifacts.js +10 -1
  207. package/dist/performance-goal/artifacts.js.map +1 -1
  208. package/dist/ralplan/__tests__/consensus-gate.test.js +112 -0
  209. package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
  210. package/dist/ralplan/consensus-gate.d.ts +23 -0
  211. package/dist/ralplan/consensus-gate.d.ts.map +1 -1
  212. package/dist/ralplan/consensus-gate.js +133 -21
  213. package/dist/ralplan/consensus-gate.js.map +1 -1
  214. package/dist/scripts/__tests__/codex-native-hook.test.js +1251 -13
  215. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  216. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  217. package/dist/scripts/codex-native-hook.js +601 -24
  218. package/dist/scripts/codex-native-hook.js.map +1 -1
  219. package/dist/scripts/notify-hook/team-leader-nudge.d.ts +1 -0
  220. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  221. package/dist/scripts/notify-hook/team-leader-nudge.js +279 -86
  222. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  223. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  224. package/dist/scripts/notify-hook/team-tmux-guard.js +87 -8
  225. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  226. package/dist/scripts/notify-hook/tmux-injection.js +1 -1
  227. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  228. package/dist/scripts/run-compiled-ci.d.ts +2 -0
  229. package/dist/scripts/run-compiled-ci.d.ts.map +1 -0
  230. package/dist/scripts/run-compiled-ci.js +77 -0
  231. package/dist/scripts/run-compiled-ci.js.map +1 -0
  232. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  233. package/dist/scripts/sync-plugin-mirror.js +1 -0
  234. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  235. package/dist/session-history/search.d.ts.map +1 -1
  236. package/dist/session-history/search.js +24 -9
  237. package/dist/session-history/search.js.map +1 -1
  238. package/dist/sidecar/__tests__/args.test.d.ts +2 -0
  239. package/dist/sidecar/__tests__/args.test.d.ts.map +1 -0
  240. package/dist/sidecar/__tests__/args.test.js +18 -0
  241. package/dist/sidecar/__tests__/args.test.js.map +1 -0
  242. package/dist/sidecar/index.d.ts.map +1 -1
  243. package/dist/sidecar/index.js +12 -4
  244. package/dist/sidecar/index.js.map +1 -1
  245. package/dist/state/__tests__/operations.test.js +107 -3
  246. package/dist/state/__tests__/operations.test.js.map +1 -1
  247. package/dist/state/operations.d.ts.map +1 -1
  248. package/dist/state/operations.js +57 -2
  249. package/dist/state/operations.js.map +1 -1
  250. package/dist/team/__tests__/delivery-e2e-smoke.test.js +22 -1
  251. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
  252. package/dist/team/__tests__/model-contract.test.js +57 -1
  253. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  254. package/dist/team/__tests__/runtime.test.js +1468 -110
  255. package/dist/team/__tests__/runtime.test.js.map +1 -1
  256. package/dist/team/__tests__/scaling.test.js +63 -0
  257. package/dist/team/__tests__/scaling.test.js.map +1 -1
  258. package/dist/team/__tests__/state.test.js +24 -1
  259. package/dist/team/__tests__/state.test.js.map +1 -1
  260. package/dist/team/__tests__/tmux-session.test.js +512 -0
  261. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  262. package/dist/team/__tests__/worker-bootstrap.test.js +42 -9
  263. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  264. package/dist/team/model-contract.d.ts +16 -0
  265. package/dist/team/model-contract.d.ts.map +1 -1
  266. package/dist/team/model-contract.js +41 -1
  267. package/dist/team/model-contract.js.map +1 -1
  268. package/dist/team/runtime.d.ts.map +1 -1
  269. package/dist/team/runtime.js +116 -30
  270. package/dist/team/runtime.js.map +1 -1
  271. package/dist/team/scaling.d.ts.map +1 -1
  272. package/dist/team/scaling.js +9 -1
  273. package/dist/team/scaling.js.map +1 -1
  274. package/dist/team/state/types.d.ts +2 -0
  275. package/dist/team/state/types.d.ts.map +1 -1
  276. package/dist/team/state/types.js.map +1 -1
  277. package/dist/team/state.d.ts +3 -0
  278. package/dist/team/state.d.ts.map +1 -1
  279. package/dist/team/state.js +20 -0
  280. package/dist/team/state.js.map +1 -1
  281. package/dist/team/tmux-session.d.ts +38 -3
  282. package/dist/team/tmux-session.d.ts.map +1 -1
  283. package/dist/team/tmux-session.js +275 -36
  284. package/dist/team/tmux-session.js.map +1 -1
  285. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  286. package/dist/team/worker-bootstrap.js +26 -1
  287. package/dist/team/worker-bootstrap.js.map +1 -1
  288. package/dist/ultragoal/__tests__/artifacts.test.js +388 -0
  289. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  290. package/dist/ultragoal/__tests__/docs-contract.test.js +3 -0
  291. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  292. package/dist/ultragoal/artifacts.d.ts +23 -0
  293. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  294. package/dist/ultragoal/artifacts.js +275 -12
  295. package/dist/ultragoal/artifacts.js.map +1 -1
  296. package/dist/url-reader/__tests__/url-reader.test.d.ts +2 -0
  297. package/dist/url-reader/__tests__/url-reader.test.d.ts.map +1 -0
  298. package/dist/url-reader/__tests__/url-reader.test.js +433 -0
  299. package/dist/url-reader/__tests__/url-reader.test.js.map +1 -0
  300. package/dist/url-reader/index.d.ts +4 -0
  301. package/dist/url-reader/index.d.ts.map +1 -0
  302. package/dist/url-reader/index.js +522 -0
  303. package/dist/url-reader/index.js.map +1 -0
  304. package/dist/url-reader/types.d.ts +41 -0
  305. package/dist/url-reader/types.d.ts.map +1 -0
  306. package/dist/url-reader/types.js +2 -0
  307. package/dist/url-reader/types.js.map +1 -0
  308. package/dist/utils/__tests__/agents-md.test.js +39 -1
  309. package/dist/utils/__tests__/agents-md.test.js.map +1 -1
  310. package/dist/utils/__tests__/agents-model-table.test.js +28 -0
  311. package/dist/utils/__tests__/agents-model-table.test.js.map +1 -1
  312. package/dist/utils/agents-md.d.ts +4 -0
  313. package/dist/utils/agents-md.d.ts.map +1 -1
  314. package/dist/utils/agents-md.js +28 -0
  315. package/dist/utils/agents-md.js.map +1 -1
  316. package/dist/utils/agents-model-table.d.ts +7 -3
  317. package/dist/utils/agents-model-table.d.ts.map +1 -1
  318. package/dist/utils/agents-model-table.js +16 -8
  319. package/dist/utils/agents-model-table.js.map +1 -1
  320. package/dist/utils/platform-command.d.ts +7 -1
  321. package/dist/utils/platform-command.d.ts.map +1 -1
  322. package/dist/utils/platform-command.js +12 -1
  323. package/dist/utils/platform-command.js.map +1 -1
  324. package/dist/verification/__tests__/ci-rust-gates.test.js +4 -0
  325. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  326. package/dist/vscode/__tests__/index.test.d.ts +2 -0
  327. package/dist/vscode/__tests__/index.test.d.ts.map +1 -0
  328. package/dist/vscode/__tests__/index.test.js +236 -0
  329. package/dist/vscode/__tests__/index.test.js.map +1 -0
  330. package/dist/vscode/index.d.ts +76 -0
  331. package/dist/vscode/index.d.ts.map +1 -0
  332. package/dist/vscode/index.js +196 -0
  333. package/dist/vscode/index.js.map +1 -0
  334. package/package.json +3 -3
  335. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  336. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +59 -8
  337. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +9 -5
  338. package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +3 -0
  339. package/plugins/oh-my-codex/skills/performance-goal/SKILL.md +3 -0
  340. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +1 -1
  341. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +22 -4
  342. package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +2 -2
  343. package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +61 -0
  344. package/skills/autopilot/SKILL.md +9 -5
  345. package/skills/autoresearch-goal/SKILL.md +3 -0
  346. package/skills/ecomode/SKILL.md +1 -1
  347. package/skills/ecomode/references/agent-tiers.md +61 -0
  348. package/skills/performance-goal/SKILL.md +3 -0
  349. package/skills/ralplan/SKILL.md +1 -1
  350. package/skills/ultragoal/SKILL.md +22 -4
  351. package/skills/ultrawork/SKILL.md +2 -2
  352. package/skills/ultrawork/references/agent-tiers.md +61 -0
  353. package/src/scripts/__tests__/codex-native-hook.test.ts +1560 -181
  354. package/src/scripts/codex-native-hook.ts +663 -24
  355. package/src/scripts/notify-hook/team-leader-nudge.ts +298 -91
  356. package/src/scripts/notify-hook/team-tmux-guard.ts +92 -8
  357. package/src/scripts/notify-hook/tmux-injection.ts +1 -1
  358. package/src/scripts/run-compiled-ci.ts +85 -0
  359. package/src/scripts/sync-plugin-mirror.ts +1 -0
  360. package/templates/AGENTS.md +6 -0
@@ -35,6 +35,18 @@ function withMockedExistsSync(mock, fn) {
35
35
  syncBuiltinESMExports();
36
36
  }
37
37
  }
38
+ function withMockedStatSync(mock, fn) {
39
+ const original = fs.statSync;
40
+ fs.statSync = mock;
41
+ syncBuiltinESMExports();
42
+ try {
43
+ return fn();
44
+ }
45
+ finally {
46
+ fs.statSync = original;
47
+ syncBuiltinESMExports();
48
+ }
49
+ }
38
50
  function escapeRegExp(value) {
39
51
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
40
52
  }
@@ -3219,6 +3231,9 @@ esac
3219
3231
  assert.match(tmuxLog, /set-option -p -t %1 @omx_pane_instance_id omx-pane-scope/);
3220
3232
  assert.match(tmuxLog, /set-option -p -t %2 @omx_pane_instance_id omx-pane-scope/);
3221
3233
  assert.match(tmuxLog, /set-option -p -t %3 @omx_pane_instance_id omx-pane-scope/);
3234
+ assert.match(tmuxLog, /set-option -p -t %1 @omx_team_pane_owner_id team:pane-tags/);
3235
+ assert.match(tmuxLog, /set-option -p -t %2 @omx_team_pane_owner_id team:pane-tags/);
3236
+ assert.match(tmuxLog, /set-option -p -t %3 @omx_team_pane_owner_id team:pane-tags/);
3222
3237
  assert.match(tmuxLog, /exec env OMX_SESSION_ID='omx-pane-scope' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' .*hud --watch/);
3223
3238
  });
3224
3239
  }
@@ -3242,6 +3257,202 @@ esac
3242
3257
  await rm(cwd, { recursive: true, force: true });
3243
3258
  }
3244
3259
  });
3260
+ it('does not reuse the Team pane owner token as the HUD logical session id', async () => {
3261
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-team-hud-session-boundary-'));
3262
+ const prevTmux = process.env.TMUX;
3263
+ const prevTmuxPane = process.env.TMUX_PANE;
3264
+ const prevSessionId = process.env.OMX_SESSION_ID;
3265
+ const prevWorkerCli = process.env.OMX_TEAM_WORKER_CLI;
3266
+ try {
3267
+ await withMockTmuxFixture('omx-tmux-hud-session-boundary-', (logPath) => `#!/bin/sh
3268
+ set -eu
3269
+ printf '%s\\n' "$*" >> "${logPath}"
3270
+ case "\${1:-}" in
3271
+ -V)
3272
+ echo "tmux 3.4"
3273
+ exit 0
3274
+ ;;
3275
+ display-message)
3276
+ case "$*" in
3277
+ *"#{window_width}"*)
3278
+ echo "120"
3279
+ ;;
3280
+ *)
3281
+ echo "shared:0 %1"
3282
+ ;;
3283
+ esac
3284
+ exit 0
3285
+ ;;
3286
+ list-panes)
3287
+ case "$*" in
3288
+ *"-t %2 -F #{pane_pid}"*)
3289
+ echo "2000002222"
3290
+ ;;
3291
+ *"pane_current_command"*)
3292
+ printf "%%1\\tnode\\t'codex'\\n"
3293
+ ;;
3294
+ *)
3295
+ printf "%%1\\n"
3296
+ ;;
3297
+ esac
3298
+ exit 0
3299
+ ;;
3300
+ split-window)
3301
+ case "$*" in
3302
+ *" -h "*)
3303
+ echo "%2"
3304
+ ;;
3305
+ *)
3306
+ echo "%3"
3307
+ ;;
3308
+ esac
3309
+ exit 0
3310
+ ;;
3311
+ set-option|resize-pane|select-layout|set-window-option|select-pane|set-hook|run-shell)
3312
+ exit 0
3313
+ ;;
3314
+ *)
3315
+ exit 0
3316
+ ;;
3317
+ esac
3318
+ `, async ({ logPath }) => {
3319
+ const fakeBinDir = join(logPath, '..');
3320
+ const geminiPath = join(fakeBinDir, 'gemini');
3321
+ await writeFile(geminiPath, '#!/bin/sh\nexit 0\n');
3322
+ await chmod(geminiPath, 0o755);
3323
+ process.env.TMUX = '1';
3324
+ process.env.TMUX_PANE = '%1';
3325
+ delete process.env.OMX_SESSION_ID;
3326
+ process.env.OMX_TEAM_WORKER_CLI = 'gemini';
3327
+ const session = createTeamSession('HUD Session Boundary', 1, cwd, [], undefined, {
3328
+ teamPaneOwnerId: 'team:explicit-owner-boundary',
3329
+ });
3330
+ assert.equal(session.hudPaneId, '%3');
3331
+ assert.equal(session.teamPaneOwnerId, 'team:explicit-owner-boundary');
3332
+ const tmuxLog = await readFile(logPath, 'utf-8');
3333
+ assert.match(tmuxLog, /set-option -p -t %1 @omx_team_pane_owner_id team:explicit-owner-boundary/);
3334
+ assert.match(tmuxLog, /set-option -p -t %2 @omx_team_pane_owner_id team:explicit-owner-boundary/);
3335
+ assert.match(tmuxLog, /set-option -p -t %3 @omx_team_pane_owner_id team:explicit-owner-boundary/);
3336
+ assert.match(tmuxLog, /exec env OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' .*hud --watch/);
3337
+ assert.doesNotMatch(tmuxLog, /OMX_SESSION_ID='team:explicit-owner-boundary'/);
3338
+ });
3339
+ }
3340
+ finally {
3341
+ if (typeof prevTmux === 'string')
3342
+ process.env.TMUX = prevTmux;
3343
+ else
3344
+ delete process.env.TMUX;
3345
+ if (typeof prevTmuxPane === 'string')
3346
+ process.env.TMUX_PANE = prevTmuxPane;
3347
+ else
3348
+ delete process.env.TMUX_PANE;
3349
+ if (typeof prevSessionId === 'string')
3350
+ process.env.OMX_SESSION_ID = prevSessionId;
3351
+ else
3352
+ delete process.env.OMX_SESSION_ID;
3353
+ if (typeof prevWorkerCli === 'string')
3354
+ process.env.OMX_TEAM_WORKER_CLI = prevWorkerCli;
3355
+ else
3356
+ delete process.env.OMX_TEAM_WORKER_CLI;
3357
+ await rm(cwd, { recursive: true, force: true });
3358
+ }
3359
+ });
3360
+ it('removes only HUD panes owned by the current leader during team startup', async () => {
3361
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-team-owned-hud-startup-'));
3362
+ const prevTmux = process.env.TMUX;
3363
+ const prevTmuxPane = process.env.TMUX_PANE;
3364
+ const prevSessionId = process.env.OMX_SESSION_ID;
3365
+ const prevWorkerCli = process.env.OMX_TEAM_WORKER_CLI;
3366
+ try {
3367
+ await withMockTmuxFixture('omx-tmux-owned-hud-startup-', (logPath) => `#!/bin/sh
3368
+ set -eu
3369
+ printf '%s\n' "$*" >> "${logPath}"
3370
+ case "\${1:-}" in
3371
+ -V)
3372
+ echo "tmux 3.4"
3373
+ exit 0
3374
+ ;;
3375
+ display-message)
3376
+ case "$*" in
3377
+ *"#{window_width}"*)
3378
+ echo "120"
3379
+ ;;
3380
+ *)
3381
+ echo "shared:0 %1"
3382
+ ;;
3383
+ esac
3384
+ exit 0
3385
+ ;;
3386
+ list-panes)
3387
+ case "$*" in
3388
+ *"pane_current_command"*)
3389
+ printf "%%1\\tnode\\t'codex'\\n"
3390
+ printf "%%7\\tnode\\t'codex neighbor'\\n"
3391
+ printf "%%2\\tnode\\texec env OMX_SESSION_ID='leader-session-a' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%%1' node /tmp/bin/omx.js hud --watch\\n"
3392
+ printf "%%8\\tnode\\texec env OMX_SESSION_ID='neighbor-session' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%%7' node /tmp/bin/omx.js hud --watch\\n"
3393
+ ;;
3394
+ *)
3395
+ printf "%%1\\n%%7\\n%%2\\n%%8\\n"
3396
+ ;;
3397
+ esac
3398
+ exit 0
3399
+ ;;
3400
+ split-window)
3401
+ case "$*" in
3402
+ *" -h "*)
3403
+ echo "%3"
3404
+ ;;
3405
+ *)
3406
+ echo "%4"
3407
+ ;;
3408
+ esac
3409
+ exit 0
3410
+ ;;
3411
+ set-option|resize-pane|select-layout|set-window-option|select-pane|set-hook|run-shell|send-keys|kill-pane)
3412
+ exit 0
3413
+ ;;
3414
+ *)
3415
+ exit 0
3416
+ ;;
3417
+ esac
3418
+ `, async ({ logPath }) => {
3419
+ const fakeBinDir = join(logPath, '..');
3420
+ const geminiPath = join(fakeBinDir, 'gemini');
3421
+ await writeFile(geminiPath, '#!/bin/sh\nexit 0\n');
3422
+ await chmod(geminiPath, 0o755);
3423
+ process.env.TMUX = 'shared-session,stub,0';
3424
+ process.env.TMUX_PANE = '%1';
3425
+ process.env.OMX_SESSION_ID = 'leader-session-a';
3426
+ process.env.OMX_TEAM_WORKER_CLI = 'gemini';
3427
+ const session = createTeamSession('Owned HUD Startup', 1, cwd);
3428
+ assert.equal(session.leaderPaneId, '%1');
3429
+ assert.equal(session.hudPaneId, '%4');
3430
+ const tmuxLog = await readFile(logPath, 'utf-8');
3431
+ assert.match(tmuxLog, /kill-pane -t %2/);
3432
+ assert.doesNotMatch(tmuxLog, /kill-pane -t %8/);
3433
+ assert.match(tmuxLog, /split-window -v -f -l 3 -t shared:0 -d -P -F #\{pane_id\}/);
3434
+ });
3435
+ }
3436
+ finally {
3437
+ if (typeof prevTmux === 'string')
3438
+ process.env.TMUX = prevTmux;
3439
+ else
3440
+ delete process.env.TMUX;
3441
+ if (typeof prevTmuxPane === 'string')
3442
+ process.env.TMUX_PANE = prevTmuxPane;
3443
+ else
3444
+ delete process.env.TMUX_PANE;
3445
+ if (typeof prevSessionId === 'string')
3446
+ process.env.OMX_SESSION_ID = prevSessionId;
3447
+ else
3448
+ delete process.env.OMX_SESSION_ID;
3449
+ if (typeof prevWorkerCli === 'string')
3450
+ process.env.OMX_TEAM_WORKER_CLI = prevWorkerCli;
3451
+ else
3452
+ delete process.env.OMX_TEAM_WORKER_CLI;
3453
+ await rm(cwd, { recursive: true, force: true });
3454
+ }
3455
+ });
3245
3456
  it('uses tmux 3.2a-compatible client-resized hook registration for team HUD resize', async () => {
3246
3457
  const cwd = await mkdtemp(join(tmpdir(), 'omx-team-resize-hook-fallback-'));
3247
3458
  const prevTmux = process.env.TMUX;
@@ -3911,6 +4122,307 @@ esac
3911
4122
  await rm(cwd, { recursive: true, force: true });
3912
4123
  }
3913
4124
  });
4125
+ it('restores standalone HUD panes from the live leader pane cwd with explicit session ownership', async () => {
4126
+ const teamLaunchCwd = await mkdtemp(join(tmpdir(), 'omx-standalone-team-launch-cwd-'));
4127
+ const leaderPaneCwd = await mkdtemp(join(tmpdir(), 'omx-standalone-leader-pane-cwd-'));
4128
+ try {
4129
+ await withMockTmuxFixture('omx-tmux-leader-cwd-standalone-hud-', (logPath) => `#!/bin/sh
4130
+ set -eu
4131
+ printf '%s\\n' "$*" >> "${logPath}"
4132
+ case "\${1:-}" in
4133
+ display-message)
4134
+ case "$*" in
4135
+ *"#{pane_current_path}"*)
4136
+ echo "${leaderPaneCwd}"
4137
+ ;;
4138
+ esac
4139
+ exit 0
4140
+ ;;
4141
+ split-window)
4142
+ echo "%44"
4143
+ exit 0
4144
+ ;;
4145
+ run-shell|select-pane|resize-pane|set-hook)
4146
+ exit 0
4147
+ ;;
4148
+ *)
4149
+ exit 0
4150
+ ;;
4151
+ esac
4152
+ `, async ({ logPath }) => {
4153
+ const paneId = restoreStandaloneHudPane('%11', teamLaunchCwd, {
4154
+ sessionId: 'current-session-for-hud',
4155
+ });
4156
+ assert.equal(paneId, '%44');
4157
+ const tmuxLog = await readFile(logPath, 'utf-8');
4158
+ assert.match(tmuxLog, /display-message -p -t %11 #\{pane_current_path\}/);
4159
+ assert.match(tmuxLog, new RegExp(`split-window -v -l ${HUD_TMUX_TEAM_HEIGHT_LINES} -t %11 -d -P -F #\\{pane_id\\} -c ${escapeRegExp(leaderPaneCwd)} `));
4160
+ assert.doesNotMatch(tmuxLog, new RegExp(`split-window .* -c ${escapeRegExp(teamLaunchCwd)} `));
4161
+ assert.match(tmuxLog, /exec env OMX_SESSION_ID='current-session-for-hud' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%11' .*hud --watch/);
4162
+ });
4163
+ }
4164
+ finally {
4165
+ await rm(teamLaunchCwd, { recursive: true, force: true });
4166
+ await rm(leaderPaneCwd, { recursive: true, force: true });
4167
+ }
4168
+ });
4169
+ it('falls back to the team launch cwd when the live leader pane cwd is unusable', async () => {
4170
+ const teamLaunchCwd = await mkdtemp(join(tmpdir(), 'omx-standalone-team-launch-cwd-fallback-'));
4171
+ const deletedLeaderPaneCwd = await mkdtemp(join(tmpdir(), 'omx-standalone-deleted-leader-pane-cwd-'));
4172
+ await rm(deletedLeaderPaneCwd, { recursive: true, force: true });
4173
+ try {
4174
+ await withMockTmuxFixture('omx-tmux-deleted-leader-cwd-standalone-hud-', (logPath) => `#!/bin/sh
4175
+ set -eu
4176
+ printf '%s\\n' "$*" >> "${logPath}"
4177
+ case "\${1:-}" in
4178
+ display-message)
4179
+ case "$*" in
4180
+ *"#{pane_current_path}"*)
4181
+ echo "${deletedLeaderPaneCwd}"
4182
+ ;;
4183
+ esac
4184
+ exit 0
4185
+ ;;
4186
+ split-window)
4187
+ case "$*" in
4188
+ *"-c ${teamLaunchCwd} "*)
4189
+ echo "%44"
4190
+ exit 0
4191
+ ;;
4192
+ *"-c ${deletedLeaderPaneCwd} "*)
4193
+ echo "deleted cwd should not be used" >&2
4194
+ exit 1
4195
+ ;;
4196
+ *)
4197
+ echo "unexpected cwd: $*" >&2
4198
+ exit 1
4199
+ ;;
4200
+ esac
4201
+ ;;
4202
+ run-shell|select-pane|resize-pane|set-hook)
4203
+ exit 0
4204
+ ;;
4205
+ *)
4206
+ exit 0
4207
+ ;;
4208
+ esac
4209
+ `, async ({ logPath }) => {
4210
+ const paneId = restoreStandaloneHudPane('%11', teamLaunchCwd, {
4211
+ sessionId: 'current-session-for-hud',
4212
+ });
4213
+ assert.equal(paneId, '%44');
4214
+ const tmuxLog = await readFile(logPath, 'utf-8');
4215
+ assert.match(tmuxLog, /display-message -p -t %11 #\{pane_current_path\}/);
4216
+ assert.match(tmuxLog, new RegExp(`split-window -v -l ${HUD_TMUX_TEAM_HEIGHT_LINES} -t %11 -d -P -F #\\{pane_id\\} -c ${escapeRegExp(teamLaunchCwd)} `));
4217
+ assert.doesNotMatch(tmuxLog, new RegExp(`split-window .* -c ${escapeRegExp(deletedLeaderPaneCwd)} `));
4218
+ assert.match(tmuxLog, /select-pane -t %11/);
4219
+ });
4220
+ }
4221
+ finally {
4222
+ await rm(teamLaunchCwd, { recursive: true, force: true });
4223
+ }
4224
+ });
4225
+ it('keeps MSYS drive-style live leader cwd candidates without raw stat prefiltering', async () => {
4226
+ const liveLeaderCwd = '/c/live';
4227
+ const fallbackCwd = 'C:\\fallback';
4228
+ const fakeCygpathDir = await mkdtemp(join(tmpdir(), 'omx-msys-live-cygpath-'));
4229
+ const previousPath = process.env.PATH;
4230
+ const previousMsystem = process.env.MSYSTEM;
4231
+ const previousOstype = process.env.OSTYPE;
4232
+ const previousWsl = process.env.WSL_DISTRO_NAME;
4233
+ const previousWslInterop = process.env.WSL_INTEROP;
4234
+ const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform');
4235
+ const statCalls = [];
4236
+ try {
4237
+ const cygpathPath = join(fakeCygpathDir, 'cygpath');
4238
+ await writeFile(cygpathPath, '#!/bin/sh\nprintf "%s\\n" "$2"\n');
4239
+ await chmod(cygpathPath, 0o755);
4240
+ process.env.PATH = `${fakeCygpathDir}:${previousPath ?? ''}`;
4241
+ process.env.MSYSTEM = 'MINGW64';
4242
+ process.env.OSTYPE = 'msys';
4243
+ delete process.env.WSL_DISTRO_NAME;
4244
+ delete process.env.WSL_INTEROP;
4245
+ Object.defineProperty(process, 'platform', { value: 'win32', configurable: true });
4246
+ await withMockTmuxFixture('omx-tmux-msys-live-cwd-standalone-hud-', (logPath) => `#!/bin/sh
4247
+ set -eu
4248
+ printf '%s\\n' "$*" >> "${logPath}"
4249
+ case "\${1:-}" in
4250
+ display-message)
4251
+ case "$*" in
4252
+ *"#{pane_current_path}"*)
4253
+ echo "${liveLeaderCwd}"
4254
+ ;;
4255
+ esac
4256
+ exit 0
4257
+ ;;
4258
+ split-window)
4259
+ case "$*" in
4260
+ *"-c ${liveLeaderCwd} "*)
4261
+ echo "%44"
4262
+ exit 0
4263
+ ;;
4264
+ *"-c ${fallbackCwd} "*)
4265
+ echo "fallback cwd should not be used when MSYS live cwd succeeds" >&2
4266
+ exit 1
4267
+ ;;
4268
+ *)
4269
+ echo "unexpected cwd: $*" >&2
4270
+ exit 1
4271
+ ;;
4272
+ esac
4273
+ ;;
4274
+ run-shell|select-pane|resize-pane|set-hook)
4275
+ exit 0
4276
+ ;;
4277
+ *)
4278
+ exit 0
4279
+ ;;
4280
+ esac
4281
+ `, async ({ logPath }) => {
4282
+ const paneId = withMockedStatSync(((pathLike) => {
4283
+ const value = String(pathLike);
4284
+ statCalls.push(value);
4285
+ if (value === fallbackCwd)
4286
+ return { isDirectory: () => true };
4287
+ return { isDirectory: () => false };
4288
+ }), () => restoreStandaloneHudPane('%11', fallbackCwd, { sessionId: 'current-session-for-hud' }));
4289
+ assert.equal(paneId, '%44');
4290
+ assert.equal(statCalls.includes(liveLeaderCwd), false);
4291
+ assert.equal(statCalls.includes(fallbackCwd), true);
4292
+ const tmuxLog = await readFile(logPath, 'utf-8');
4293
+ assert.match(tmuxLog, /display-message -p -t %11 #\{pane_current_path\}/);
4294
+ assert.match(tmuxLog, new RegExp(`split-window -v -l ${HUD_TMUX_TEAM_HEIGHT_LINES} -t %11 -d -P -F #\\{pane_id\\} -c ${escapeRegExp(liveLeaderCwd)} `));
4295
+ assert.doesNotMatch(tmuxLog, new RegExp(`split-window .* -c ${escapeRegExp(fallbackCwd)} `));
4296
+ assert.match(tmuxLog, /select-pane -t %11/);
4297
+ });
4298
+ }
4299
+ finally {
4300
+ if (originalPlatform)
4301
+ Object.defineProperty(process, 'platform', originalPlatform);
4302
+ if (typeof previousPath === 'string')
4303
+ process.env.PATH = previousPath;
4304
+ else
4305
+ delete process.env.PATH;
4306
+ if (typeof previousMsystem === 'string')
4307
+ process.env.MSYSTEM = previousMsystem;
4308
+ else
4309
+ delete process.env.MSYSTEM;
4310
+ if (typeof previousOstype === 'string')
4311
+ process.env.OSTYPE = previousOstype;
4312
+ else
4313
+ delete process.env.OSTYPE;
4314
+ if (typeof previousWsl === 'string')
4315
+ process.env.WSL_DISTRO_NAME = previousWsl;
4316
+ else
4317
+ delete process.env.WSL_DISTRO_NAME;
4318
+ if (typeof previousWslInterop === 'string')
4319
+ process.env.WSL_INTEROP = previousWslInterop;
4320
+ else
4321
+ delete process.env.WSL_INTEROP;
4322
+ await rm(fakeCygpathDir, { recursive: true, force: true });
4323
+ }
4324
+ });
4325
+ it('falls back after an unusable MSYS drive-style live leader cwd split attempt fails', async () => {
4326
+ const liveLeaderCwd = '/c/deleted-live';
4327
+ const fallbackCwd = 'C:\\fallback';
4328
+ const fakeCygpathDir = await mkdtemp(join(tmpdir(), 'omx-msys-deleted-live-cygpath-'));
4329
+ const previousPath = process.env.PATH;
4330
+ const previousMsystem = process.env.MSYSTEM;
4331
+ const previousOstype = process.env.OSTYPE;
4332
+ const previousWsl = process.env.WSL_DISTRO_NAME;
4333
+ const previousWslInterop = process.env.WSL_INTEROP;
4334
+ const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform');
4335
+ const statCalls = [];
4336
+ try {
4337
+ const cygpathPath = join(fakeCygpathDir, 'cygpath');
4338
+ await writeFile(cygpathPath, '#!/bin/sh\nprintf "%s\\n" "$2"\n');
4339
+ await chmod(cygpathPath, 0o755);
4340
+ process.env.PATH = `${fakeCygpathDir}:${previousPath ?? ''}`;
4341
+ process.env.MSYSTEM = 'MINGW64';
4342
+ process.env.OSTYPE = 'msys';
4343
+ delete process.env.WSL_DISTRO_NAME;
4344
+ delete process.env.WSL_INTEROP;
4345
+ Object.defineProperty(process, 'platform', { value: 'win32', configurable: true });
4346
+ await withMockTmuxFixture('omx-tmux-msys-deleted-live-cwd-standalone-hud-', (logPath) => `#!/bin/sh
4347
+ set -eu
4348
+ printf '%s\\n' "$*" >> "${logPath}"
4349
+ case "\${1:-}" in
4350
+ display-message)
4351
+ case "$*" in
4352
+ *"#{pane_current_path}"*)
4353
+ echo "${liveLeaderCwd}"
4354
+ ;;
4355
+ esac
4356
+ exit 0
4357
+ ;;
4358
+ split-window)
4359
+ case "$*" in
4360
+ *"-c ${liveLeaderCwd} "*)
4361
+ echo "deleted live cwd cannot be used" >&2
4362
+ exit 1
4363
+ ;;
4364
+ *"-c ${fallbackCwd} "*)
4365
+ echo "%44"
4366
+ exit 0
4367
+ ;;
4368
+ *)
4369
+ echo "unexpected cwd: $*" >&2
4370
+ exit 1
4371
+ ;;
4372
+ esac
4373
+ ;;
4374
+ run-shell|select-pane|resize-pane|set-hook)
4375
+ exit 0
4376
+ ;;
4377
+ *)
4378
+ exit 0
4379
+ ;;
4380
+ esac
4381
+ `, async ({ logPath }) => {
4382
+ const paneId = withMockedStatSync(((pathLike) => {
4383
+ const value = String(pathLike);
4384
+ statCalls.push(value);
4385
+ if (value === fallbackCwd)
4386
+ return { isDirectory: () => true };
4387
+ return { isDirectory: () => false };
4388
+ }), () => restoreStandaloneHudPane('%11', fallbackCwd, { sessionId: 'current-session-for-hud' }));
4389
+ assert.equal(paneId, '%44');
4390
+ assert.equal(statCalls.includes(liveLeaderCwd), false);
4391
+ assert.equal(statCalls.includes(fallbackCwd), true);
4392
+ const tmuxLog = await readFile(logPath, 'utf-8');
4393
+ const liveAttemptIndex = tmuxLog.indexOf(`-c ${liveLeaderCwd} `);
4394
+ const fallbackAttemptIndex = tmuxLog.indexOf(`-c ${fallbackCwd} `);
4395
+ assert.ok(liveAttemptIndex >= 0, 'deleted MSYS live cwd should still be attempted');
4396
+ assert.ok(fallbackAttemptIndex > liveAttemptIndex, 'fallback should be attempted after live split failure');
4397
+ assert.match(tmuxLog, /select-pane -t %11/);
4398
+ });
4399
+ }
4400
+ finally {
4401
+ if (originalPlatform)
4402
+ Object.defineProperty(process, 'platform', originalPlatform);
4403
+ if (typeof previousPath === 'string')
4404
+ process.env.PATH = previousPath;
4405
+ else
4406
+ delete process.env.PATH;
4407
+ if (typeof previousMsystem === 'string')
4408
+ process.env.MSYSTEM = previousMsystem;
4409
+ else
4410
+ delete process.env.MSYSTEM;
4411
+ if (typeof previousOstype === 'string')
4412
+ process.env.OSTYPE = previousOstype;
4413
+ else
4414
+ delete process.env.OSTYPE;
4415
+ if (typeof previousWsl === 'string')
4416
+ process.env.WSL_DISTRO_NAME = previousWsl;
4417
+ else
4418
+ delete process.env.WSL_DISTRO_NAME;
4419
+ if (typeof previousWslInterop === 'string')
4420
+ process.env.WSL_INTEROP = previousWslInterop;
4421
+ else
4422
+ delete process.env.WSL_INTEROP;
4423
+ await rm(fakeCygpathDir, { recursive: true, force: true });
4424
+ }
4425
+ });
3914
4426
  it('restores standalone HUD panes with an absolute OMX entry path after cwd drift', async () => {
3915
4427
  const cwd = await mkdtemp(join(tmpdir(), 'omx-standalone-relative-hud-'));
3916
4428
  const startupCwd = await mkdtemp(join(tmpdir(), 'omx-standalone-relative-start-'));