oh-my-codex 0.20.3 → 0.20.5

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 (661) hide show
  1. package/Cargo.lock +35 -18
  2. package/Cargo.toml +1 -1
  3. package/README.md +2 -2
  4. package/crates/omx-runtime/Cargo.toml +3 -0
  5. package/crates/omx-runtime/src/main.rs +390 -0
  6. package/crates/omx-runtime/tests/execution.rs +264 -0
  7. package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
  8. package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
  9. package/dist/adapt/__tests__/herdr-target.test.js +72 -0
  10. package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
  11. package/dist/adapt/contracts.d.ts +1 -1
  12. package/dist/adapt/contracts.d.ts.map +1 -1
  13. package/dist/adapt/contracts.js +1 -1
  14. package/dist/adapt/contracts.js.map +1 -1
  15. package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
  16. package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
  17. package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
  18. package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
  19. package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
  20. package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
  21. package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
  22. package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
  23. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
  24. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
  25. package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
  26. package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
  27. package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
  28. package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
  29. package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
  30. package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
  31. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
  32. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
  33. package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
  34. package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
  35. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
  36. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
  37. package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
  38. package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
  39. package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
  40. package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
  41. package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
  42. package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
  43. package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
  44. package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
  45. package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
  46. package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
  47. package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
  48. package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
  49. package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
  50. package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
  51. package/dist/adapt/herdr/authority.d.ts +34 -0
  52. package/dist/adapt/herdr/authority.d.ts.map +1 -0
  53. package/dist/adapt/herdr/authority.js +71 -0
  54. package/dist/adapt/herdr/authority.js.map +1 -0
  55. package/dist/adapt/herdr/bridge.d.ts +84 -0
  56. package/dist/adapt/herdr/bridge.d.ts.map +1 -0
  57. package/dist/adapt/herdr/bridge.js +222 -0
  58. package/dist/adapt/herdr/bridge.js.map +1 -0
  59. package/dist/adapt/herdr/sanitize.d.ts +20 -0
  60. package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
  61. package/dist/adapt/herdr/sanitize.js +70 -0
  62. package/dist/adapt/herdr/sanitize.js.map +1 -0
  63. package/dist/adapt/herdr/semantic.d.ts +67 -0
  64. package/dist/adapt/herdr/semantic.d.ts.map +1 -0
  65. package/dist/adapt/herdr/semantic.js +170 -0
  66. package/dist/adapt/herdr/semantic.js.map +1 -0
  67. package/dist/adapt/herdr/seq-store.d.ts +32 -0
  68. package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
  69. package/dist/adapt/herdr/seq-store.js +126 -0
  70. package/dist/adapt/herdr/seq-store.js.map +1 -0
  71. package/dist/adapt/herdr/team-map.d.ts +30 -0
  72. package/dist/adapt/herdr/team-map.d.ts.map +1 -0
  73. package/dist/adapt/herdr/team-map.js +37 -0
  74. package/dist/adapt/herdr/team-map.js.map +1 -0
  75. package/dist/adapt/herdr/transport.d.ts +115 -0
  76. package/dist/adapt/herdr/transport.d.ts.map +1 -0
  77. package/dist/adapt/herdr/transport.js +260 -0
  78. package/dist/adapt/herdr/transport.js.map +1 -0
  79. package/dist/adapt/herdr/wiring.d.ts +24 -0
  80. package/dist/adapt/herdr/wiring.d.ts.map +1 -0
  81. package/dist/adapt/herdr/wiring.js +62 -0
  82. package/dist/adapt/herdr/wiring.js.map +1 -0
  83. package/dist/adapt/herdr.d.ts +19 -0
  84. package/dist/adapt/herdr.d.ts.map +1 -0
  85. package/dist/adapt/herdr.js +115 -0
  86. package/dist/adapt/herdr.js.map +1 -0
  87. package/dist/adapt/index.d.ts +4 -0
  88. package/dist/adapt/index.d.ts.map +1 -1
  89. package/dist/adapt/index.js +48 -0
  90. package/dist/adapt/index.js.map +1 -1
  91. package/dist/adapt/registry.d.ts.map +1 -1
  92. package/dist/adapt/registry.js +11 -0
  93. package/dist/adapt/registry.js.map +1 -1
  94. package/dist/auth/__tests__/hotswap.test.js +60 -1
  95. package/dist/auth/__tests__/hotswap.test.js.map +1 -1
  96. package/dist/auth/__tests__/storage.test.js +33 -1
  97. package/dist/auth/__tests__/storage.test.js.map +1 -1
  98. package/dist/auth/hotswap.d.ts +16 -2
  99. package/dist/auth/hotswap.d.ts.map +1 -1
  100. package/dist/auth/hotswap.js +22 -7
  101. package/dist/auth/hotswap.js.map +1 -1
  102. package/dist/auth/storage.js +1 -1
  103. package/dist/auth/storage.js.map +1 -1
  104. package/dist/autopilot/__tests__/ralplan-gate.test.js +86 -1333
  105. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
  106. package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
  107. package/dist/autopilot/ralplan-gate.js +7 -6
  108. package/dist/autopilot/ralplan-gate.js.map +1 -1
  109. package/dist/cli/__tests__/agents-init.test.js +4 -23
  110. package/dist/cli/__tests__/agents-init.test.js.map +1 -1
  111. package/dist/cli/__tests__/api.test.js +61 -24
  112. package/dist/cli/__tests__/api.test.js.map +1 -1
  113. package/dist/cli/__tests__/auth.test.js +3 -1
  114. package/dist/cli/__tests__/auth.test.js.map +1 -1
  115. package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
  116. package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
  117. package/dist/cli/__tests__/codex-plugin-layout.test.js +70 -2
  118. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  119. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
  120. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
  121. package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
  122. package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
  123. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
  124. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
  125. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
  126. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
  127. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
  128. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
  129. package/dist/cli/__tests__/doctor-state-root-binding.test.js +139 -0
  130. package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
  131. package/dist/cli/__tests__/doctor-warning-copy.test.js +35 -3
  132. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  133. package/dist/cli/__tests__/exec.test.js +75 -0
  134. package/dist/cli/__tests__/exec.test.js.map +1 -1
  135. package/dist/cli/__tests__/index.test.js +621 -460
  136. package/dist/cli/__tests__/index.test.js.map +1 -1
  137. package/dist/cli/__tests__/launch-fallback.test.js +1020 -143
  138. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  139. package/dist/cli/__tests__/mcp-parity.test.js +4 -3
  140. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  141. package/dist/cli/__tests__/native-assets.test.js +398 -16
  142. package/dist/cli/__tests__/native-assets.test.js.map +1 -1
  143. package/dist/cli/__tests__/native-hook-claim-journal.test.js +53 -5
  144. package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
  145. package/dist/cli/__tests__/ralph.test.js +2 -2
  146. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  147. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +57 -57
  148. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
  149. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
  150. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
  151. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
  152. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
  153. package/dist/cli/__tests__/ralplan.test.js +84 -12
  154. package/dist/cli/__tests__/ralplan.test.js.map +1 -1
  155. package/dist/cli/__tests__/session-scoped-runtime.test.js +1118 -43
  156. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  157. package/dist/cli/__tests__/setup-agents-overwrite.test.js +8 -55
  158. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  159. package/dist/cli/__tests__/setup-install-mode.test.js +183 -4
  160. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  161. package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
  162. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  163. package/dist/cli/__tests__/team.test.js +45 -1
  164. package/dist/cli/__tests__/team.test.js.map +1 -1
  165. package/dist/cli/__tests__/ultragoal.test.js +117 -2
  166. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  167. package/dist/cli/__tests__/uninstall.test.js +50 -5
  168. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  169. package/dist/cli/__tests__/update.test.js +669 -177
  170. package/dist/cli/__tests__/update.test.js.map +1 -1
  171. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +32 -2
  172. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  173. package/dist/cli/api.d.ts.map +1 -1
  174. package/dist/cli/api.js +9 -10
  175. package/dist/cli/api.js.map +1 -1
  176. package/dist/cli/codex-feature-probe.d.ts +16 -0
  177. package/dist/cli/codex-feature-probe.d.ts.map +1 -1
  178. package/dist/cli/codex-feature-probe.js +44 -0
  179. package/dist/cli/codex-feature-probe.js.map +1 -1
  180. package/dist/cli/codex-home.d.ts.map +1 -1
  181. package/dist/cli/codex-home.js +7 -4
  182. package/dist/cli/codex-home.js.map +1 -1
  183. package/dist/cli/doctor.d.ts +17 -0
  184. package/dist/cli/doctor.d.ts.map +1 -1
  185. package/dist/cli/doctor.js +277 -3
  186. package/dist/cli/doctor.js.map +1 -1
  187. package/dist/cli/index.d.ts +231 -12
  188. package/dist/cli/index.d.ts.map +1 -1
  189. package/dist/cli/index.js +2298 -735
  190. package/dist/cli/index.js.map +1 -1
  191. package/dist/cli/native-assets.d.ts +25 -0
  192. package/dist/cli/native-assets.d.ts.map +1 -1
  193. package/dist/cli/native-assets.js +448 -51
  194. package/dist/cli/native-assets.js.map +1 -1
  195. package/dist/cli/native-hook-claim-journal.d.ts +8 -4
  196. package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
  197. package/dist/cli/native-hook-claim-journal.js +30 -8
  198. package/dist/cli/native-hook-claim-journal.js.map +1 -1
  199. package/dist/cli/package-manager-ownership.d.ts +63 -0
  200. package/dist/cli/package-manager-ownership.d.ts.map +1 -0
  201. package/dist/cli/package-manager-ownership.js +323 -0
  202. package/dist/cli/package-manager-ownership.js.map +1 -0
  203. package/dist/cli/ralph.js +2 -2
  204. package/dist/cli/ralph.js.map +1 -1
  205. package/dist/cli/ralplan.d.ts +4 -2
  206. package/dist/cli/ralplan.d.ts.map +1 -1
  207. package/dist/cli/ralplan.js +76 -34
  208. package/dist/cli/ralplan.js.map +1 -1
  209. package/dist/cli/setup-preferences.d.ts +15 -0
  210. package/dist/cli/setup-preferences.d.ts.map +1 -1
  211. package/dist/cli/setup-preferences.js +27 -1
  212. package/dist/cli/setup-preferences.js.map +1 -1
  213. package/dist/cli/setup.d.ts +3 -0
  214. package/dist/cli/setup.d.ts.map +1 -1
  215. package/dist/cli/setup.js +55 -32
  216. package/dist/cli/setup.js.map +1 -1
  217. package/dist/cli/sparkshell.d.ts.map +1 -1
  218. package/dist/cli/sparkshell.js +52 -9
  219. package/dist/cli/sparkshell.js.map +1 -1
  220. package/dist/cli/ultragoal.d.ts.map +1 -1
  221. package/dist/cli/ultragoal.js +2 -2
  222. package/dist/cli/ultragoal.js.map +1 -1
  223. package/dist/cli/uninstall.d.ts.map +1 -1
  224. package/dist/cli/uninstall.js +27 -28
  225. package/dist/cli/uninstall.js.map +1 -1
  226. package/dist/cli/update-worker.d.ts +2 -0
  227. package/dist/cli/update-worker.d.ts.map +1 -0
  228. package/dist/cli/update-worker.js +142 -0
  229. package/dist/cli/update-worker.js.map +1 -0
  230. package/dist/cli/update.d.ts +14 -22
  231. package/dist/cli/update.d.ts.map +1 -1
  232. package/dist/cli/update.js +192 -241
  233. package/dist/cli/update.js.map +1 -1
  234. package/dist/config/__tests__/generator-idempotent.test.js +173 -29
  235. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  236. package/dist/config/__tests__/generator-notify.test.js +3 -1
  237. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  238. package/dist/config/generator.d.ts +25 -3
  239. package/dist/config/generator.d.ts.map +1 -1
  240. package/dist/config/generator.js +113 -35
  241. package/dist/config/generator.js.map +1 -1
  242. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
  243. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  244. package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
  245. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  246. package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
  247. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  248. package/dist/hooks/__tests__/agents-overlay.test.js +3 -1
  249. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  250. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -4
  251. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  252. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
  253. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
  254. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +172 -0
  255. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
  256. package/dist/hooks/__tests__/keyword-detector.test.js +172 -33
  257. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  258. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +173 -11
  259. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  260. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +1 -0
  261. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  262. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +65 -17
  263. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  264. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
  265. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  266. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
  267. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
  268. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
  269. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  270. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +2 -2
  271. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  272. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +4 -1
  273. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  274. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
  275. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
  276. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +1 -0
  277. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  278. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +9 -0
  279. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
  280. package/dist/hooks/__tests__/session.test.js +2976 -557
  281. package/dist/hooks/__tests__/session.test.js.map +1 -1
  282. package/dist/hooks/agents-overlay.js +1 -1
  283. package/dist/hooks/agents-overlay.js.map +1 -1
  284. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
  285. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  286. package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
  287. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
  288. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  289. package/dist/hooks/extensibility/dispatcher.js +20 -3
  290. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  291. package/dist/hooks/extensibility/plugin-runner.js +1 -0
  292. package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
  293. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  294. package/dist/hooks/extensibility/runtime.js.map +1 -1
  295. package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
  296. package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
  297. package/dist/hooks/extensibility/sdk/paths.js +2 -2
  298. package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
  299. package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
  300. package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
  301. package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
  302. package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
  303. package/dist/hooks/extensibility/sdk.d.ts +1 -0
  304. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  305. package/dist/hooks/extensibility/sdk.js +1 -1
  306. package/dist/hooks/extensibility/sdk.js.map +1 -1
  307. package/dist/hooks/extensibility/types.d.ts +7 -0
  308. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  309. package/dist/hooks/keyword-detector.d.ts +10 -3
  310. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  311. package/dist/hooks/keyword-detector.js +116 -20
  312. package/dist/hooks/keyword-detector.js.map +1 -1
  313. package/dist/hooks/session.d.ts +180 -14
  314. package/dist/hooks/session.d.ts.map +1 -1
  315. package/dist/hooks/session.js +1402 -281
  316. package/dist/hooks/session.js.map +1 -1
  317. package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
  318. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  319. package/dist/hud/__tests__/index.test.js +26 -16
  320. package/dist/hud/__tests__/index.test.js.map +1 -1
  321. package/dist/hud/__tests__/reconcile.test.js +83 -78
  322. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  323. package/dist/hud/__tests__/state.test.js +36 -31
  324. package/dist/hud/__tests__/state.test.js.map +1 -1
  325. package/dist/hud/__tests__/tmux.test.js +155 -198
  326. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  327. package/dist/hud/tmux.d.ts +42 -4
  328. package/dist/hud/tmux.d.ts.map +1 -1
  329. package/dist/hud/tmux.js +1017 -139
  330. package/dist/hud/tmux.js.map +1 -1
  331. package/dist/leader/__tests__/contract.test.js +71 -34
  332. package/dist/leader/__tests__/contract.test.js.map +1 -1
  333. package/dist/leader/contract.d.ts +1 -6
  334. package/dist/leader/contract.d.ts.map +1 -1
  335. package/dist/leader/contract.js +25 -24
  336. package/dist/leader/contract.js.map +1 -1
  337. package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
  338. package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
  339. package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
  340. package/dist/mcp/__tests__/state-paths.test.js +735 -4
  341. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  342. package/dist/mcp/__tests__/state-server.test.js +1 -1
  343. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  344. package/dist/mcp/__tests__/trace-server.test.js +2 -2
  345. package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
  346. package/dist/mcp/hermes-bridge.d.ts.map +1 -1
  347. package/dist/mcp/hermes-bridge.js +2 -2
  348. package/dist/mcp/hermes-bridge.js.map +1 -1
  349. package/dist/mcp/state-paths.d.ts +78 -4
  350. package/dist/mcp/state-paths.d.ts.map +1 -1
  351. package/dist/mcp/state-paths.js +543 -40
  352. package/dist/mcp/state-paths.js.map +1 -1
  353. package/dist/mcp/state-server.d.ts +4 -4
  354. package/dist/mcp/state-server.d.ts.map +1 -1
  355. package/dist/modes/__tests__/base-autopilot-gates.test.js +36 -7
  356. package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
  357. package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -1
  358. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
  359. package/dist/modes/__tests__/base-session-scope.test.js +17 -8
  360. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  361. package/dist/modes/base.d.ts +5 -5
  362. package/dist/modes/base.d.ts.map +1 -1
  363. package/dist/modes/base.js +76 -21
  364. package/dist/modes/base.js.map +1 -1
  365. package/dist/native-assets/archive.d.ts +17 -0
  366. package/dist/native-assets/archive.d.ts.map +1 -0
  367. package/dist/native-assets/archive.js +238 -0
  368. package/dist/native-assets/archive.js.map +1 -0
  369. package/dist/native-assets/policy.d.ts +42 -0
  370. package/dist/native-assets/policy.d.ts.map +1 -0
  371. package/dist/native-assets/policy.js +155 -0
  372. package/dist/native-assets/policy.js.map +1 -0
  373. package/dist/pipeline/__tests__/orchestrator.test.js +162 -40
  374. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  375. package/dist/pipeline/__tests__/stages.test.js +66 -149
  376. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  377. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  378. package/dist/pipeline/orchestrator.js +124 -18
  379. package/dist/pipeline/orchestrator.js.map +1 -1
  380. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  381. package/dist/pipeline/stages/ralplan.js +36 -8
  382. package/dist/pipeline/stages/ralplan.js.map +1 -1
  383. package/dist/ralplan/__tests__/consensus-gate.test.js +70 -1437
  384. package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
  385. package/dist/ralplan/__tests__/documented-leader-preflight.test.js +328 -39
  386. package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -1
  387. package/dist/ralplan/__tests__/runtime.test.js +82 -102
  388. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  389. package/dist/ralplan/consensus-gate.d.ts +9 -1
  390. package/dist/ralplan/consensus-gate.d.ts.map +1 -1
  391. package/dist/ralplan/consensus-gate.js +40 -304
  392. package/dist/ralplan/consensus-gate.js.map +1 -1
  393. package/dist/ralplan/documented-leader-preflight.d.ts +15 -8
  394. package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
  395. package/dist/ralplan/documented-leader-preflight.js +356 -54
  396. package/dist/ralplan/documented-leader-preflight.js.map +1 -1
  397. package/dist/ralplan/runtime.d.ts +1 -1
  398. package/dist/ralplan/runtime.d.ts.map +1 -1
  399. package/dist/ralplan/runtime.js +68 -173
  400. package/dist/ralplan/runtime.js.map +1 -1
  401. package/dist/runtime/run-state.d.ts +5 -1
  402. package/dist/runtime/run-state.d.ts.map +1 -1
  403. package/dist/runtime/run-state.js +15 -8
  404. package/dist/runtime/run-state.js.map +1 -1
  405. package/dist/scripts/__tests__/codex-native-hook.test.js +14071 -8859
  406. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  407. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
  408. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
  409. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +225 -0
  410. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
  411. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
  412. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
  413. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
  414. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
  415. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
  416. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
  417. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +259 -0
  418. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
  419. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
  420. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
  421. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +491 -0
  422. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
  423. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
  424. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
  425. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +708 -0
  426. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
  427. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
  428. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
  429. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +208 -0
  430. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
  431. package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
  432. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
  433. package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
  434. package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
  435. package/dist/scripts/__tests__/postinstall.test.js +19 -1
  436. package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
  437. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +25 -8
  438. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
  439. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +60 -25
  440. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
  441. package/dist/scripts/__tests__/smoke-packed-install.test.js +155 -16
  442. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  443. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
  444. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
  445. package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
  446. package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
  447. package/dist/scripts/codex-native-hook.d.ts +50 -1
  448. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  449. package/dist/scripts/codex-native-hook.js +3559 -451
  450. package/dist/scripts/codex-native-hook.js.map +1 -1
  451. package/dist/scripts/codex-native-pre-post.d.ts +9 -0
  452. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  453. package/dist/scripts/codex-native-pre-post.js +35 -12
  454. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  455. package/dist/scripts/generate-native-release-manifest.js +80 -51
  456. package/dist/scripts/generate-native-release-manifest.js.map +1 -1
  457. package/dist/scripts/notify-fallback-watcher.js +28 -39
  458. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  459. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  460. package/dist/scripts/notify-hook/state-io.js +5 -0
  461. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  462. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  463. package/dist/scripts/notify-hook/team-leader-nudge.js +32 -3
  464. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  465. package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
  466. package/dist/scripts/notify-hook/team-worker-stop.js +23 -3
  467. package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
  468. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  469. package/dist/scripts/notify-hook/team-worker.js +45 -5
  470. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  471. package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
  472. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  473. package/dist/scripts/notify-hook/tmux-injection.js +4 -1
  474. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  475. package/dist/scripts/notify-hook.js +78 -82
  476. package/dist/scripts/notify-hook.js.map +1 -1
  477. package/dist/scripts/postinstall-advisory.d.ts +14 -0
  478. package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
  479. package/dist/scripts/postinstall-advisory.js +49 -0
  480. package/dist/scripts/postinstall-advisory.js.map +1 -0
  481. package/dist/scripts/postinstall.d.ts +1 -1
  482. package/dist/scripts/postinstall.d.ts.map +1 -1
  483. package/dist/scripts/postinstall.js +1 -1
  484. package/dist/scripts/postinstall.js.map +1 -1
  485. package/dist/scripts/smoke-packed-install.d.ts +32 -1
  486. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  487. package/dist/scripts/smoke-packed-install.js +413 -60
  488. package/dist/scripts/smoke-packed-install.js.map +1 -1
  489. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  490. package/dist/scripts/sync-plugin-mirror.js +16 -1
  491. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  492. package/dist/scripts/verify-native-release-assets.js +37 -23
  493. package/dist/scripts/verify-native-release-assets.js.map +1 -1
  494. package/dist/state/__tests__/mode-state-context.test.js +12 -5
  495. package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
  496. package/dist/state/__tests__/operations.test.js +460 -850
  497. package/dist/state/__tests__/operations.test.js.map +1 -1
  498. package/dist/state/__tests__/skill-active.test.js +400 -2
  499. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  500. package/dist/state/mode-state-context.d.ts +3 -0
  501. package/dist/state/mode-state-context.d.ts.map +1 -1
  502. package/dist/state/mode-state-context.js +27 -13
  503. package/dist/state/mode-state-context.js.map +1 -1
  504. package/dist/state/operations.d.ts +3 -0
  505. package/dist/state/operations.d.ts.map +1 -1
  506. package/dist/state/operations.js +144 -40
  507. package/dist/state/operations.js.map +1 -1
  508. package/dist/state/skill-active.d.ts +18 -1
  509. package/dist/state/skill-active.d.ts.map +1 -1
  510. package/dist/state/skill-active.js +420 -23
  511. package/dist/state/skill-active.js.map +1 -1
  512. package/dist/state/workflow-transition-reconcile.d.ts +3 -0
  513. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  514. package/dist/state/workflow-transition-reconcile.js +10 -4
  515. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  516. package/dist/state/workflow-transition.d.ts.map +1 -1
  517. package/dist/state/workflow-transition.js +3 -1
  518. package/dist/state/workflow-transition.js.map +1 -1
  519. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +27 -0
  520. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
  521. package/dist/subagents/__tests__/tracker.test.js +837 -1048
  522. package/dist/subagents/__tests__/tracker.test.js.map +1 -1
  523. package/dist/subagents/tracker.d.ts +64 -60
  524. package/dist/subagents/tracker.d.ts.map +1 -1
  525. package/dist/subagents/tracker.js +809 -358
  526. package/dist/subagents/tracker.js.map +1 -1
  527. package/dist/team/__tests__/delivery-e2e-smoke.test.js +6 -7
  528. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
  529. package/dist/team/__tests__/mcp-comm.test.js +104 -3
  530. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  531. package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
  532. package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
  533. package/dist/team/__tests__/notice-ledger.test.js +131 -0
  534. package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
  535. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
  536. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
  537. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
  538. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
  539. package/dist/team/__tests__/phase-controller.test.js +20 -0
  540. package/dist/team/__tests__/phase-controller.test.js.map +1 -1
  541. package/dist/team/__tests__/runtime.test.js +725 -59
  542. package/dist/team/__tests__/runtime.test.js.map +1 -1
  543. package/dist/team/__tests__/scaling.test.js +222 -237
  544. package/dist/team/__tests__/scaling.test.js.map +1 -1
  545. package/dist/team/__tests__/state-root.test.js +117 -2
  546. package/dist/team/__tests__/state-root.test.js.map +1 -1
  547. package/dist/team/__tests__/tmux-session.test.js +887 -92
  548. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  549. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
  550. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
  551. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +149 -0
  552. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
  553. package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
  554. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
  555. package/dist/team/__tests__/tmux-test-fixture.js +242 -15
  556. package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
  557. package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
  558. package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
  559. package/dist/team/__tests__/worker-runtime-identity.test.js +45 -72
  560. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  561. package/dist/team/notice-ledger.d.ts +54 -0
  562. package/dist/team/notice-ledger.d.ts.map +1 -0
  563. package/dist/team/notice-ledger.js +259 -0
  564. package/dist/team/notice-ledger.js.map +1 -0
  565. package/dist/team/phase-controller.d.ts.map +1 -1
  566. package/dist/team/phase-controller.js +2 -0
  567. package/dist/team/phase-controller.js.map +1 -1
  568. package/dist/team/runtime.d.ts +3 -1
  569. package/dist/team/runtime.d.ts.map +1 -1
  570. package/dist/team/runtime.js +314 -142
  571. package/dist/team/runtime.js.map +1 -1
  572. package/dist/team/scaling.d.ts.map +1 -1
  573. package/dist/team/scaling.js +161 -91
  574. package/dist/team/scaling.js.map +1 -1
  575. package/dist/team/state/monitor.d.ts +10 -0
  576. package/dist/team/state/monitor.d.ts.map +1 -1
  577. package/dist/team/state/monitor.js +13 -0
  578. package/dist/team/state/monitor.js.map +1 -1
  579. package/dist/team/state/types.d.ts +15 -0
  580. package/dist/team/state/types.d.ts.map +1 -1
  581. package/dist/team/state/types.js.map +1 -1
  582. package/dist/team/state-root.d.ts +12 -0
  583. package/dist/team/state-root.d.ts.map +1 -1
  584. package/dist/team/state-root.js +177 -0
  585. package/dist/team/state-root.js.map +1 -1
  586. package/dist/team/state.d.ts +18 -0
  587. package/dist/team/state.d.ts.map +1 -1
  588. package/dist/team/state.js +36 -0
  589. package/dist/team/state.js.map +1 -1
  590. package/dist/team/tmux-session.d.ts +40 -4
  591. package/dist/team/tmux-session.d.ts.map +1 -1
  592. package/dist/team/tmux-session.js +513 -166
  593. package/dist/team/tmux-session.js.map +1 -1
  594. package/dist/ultragoal/__tests__/artifacts.test.js +950 -2
  595. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  596. package/dist/ultragoal/__tests__/docs-contract.test.js +1 -0
  597. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  598. package/dist/ultragoal/artifacts.d.ts +35 -1
  599. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  600. package/dist/ultragoal/artifacts.js +232 -46
  601. package/dist/ultragoal/artifacts.js.map +1 -1
  602. package/dist/utils/__tests__/file-durability.test.js +58 -1
  603. package/dist/utils/__tests__/file-durability.test.js.map +1 -1
  604. package/dist/utils/__tests__/paths.test.js +21 -1
  605. package/dist/utils/__tests__/paths.test.js.map +1 -1
  606. package/dist/utils/file-durability.d.ts +10 -0
  607. package/dist/utils/file-durability.d.ts.map +1 -1
  608. package/dist/utils/file-durability.js +34 -4
  609. package/dist/utils/file-durability.js.map +1 -1
  610. package/dist/utils/paths.d.ts.map +1 -1
  611. package/dist/utils/paths.js +14 -6
  612. package/dist/utils/paths.js.map +1 -1
  613. package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
  614. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  615. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
  616. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
  617. package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
  618. package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
  619. package/package.json +13 -5
  620. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  621. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +81 -17
  622. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +13 -5
  623. package/plugins/oh-my-codex/skills/cancel/SKILL.md +30 -85
  624. package/plugins/oh-my-codex/skills/ralph/SKILL.md +5 -5
  625. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +15 -17
  626. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +3 -2
  627. package/skills/autopilot/SKILL.md +13 -5
  628. package/skills/cancel/SKILL.md +30 -85
  629. package/skills/ralph/SKILL.md +5 -5
  630. package/skills/ralplan/SKILL.md +15 -17
  631. package/skills/ultragoal/SKILL.md +3 -2
  632. package/src/scripts/__tests__/codex-native-hook.test.ts +6091 -540
  633. package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +187 -0
  634. package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
  635. package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +187 -0
  636. package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +591 -0
  637. package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +701 -0
  638. package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +211 -0
  639. package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
  640. package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
  641. package/src/scripts/__tests__/postinstall.test.ts +23 -1
  642. package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +27 -8
  643. package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +61 -27
  644. package/src/scripts/__tests__/smoke-packed-install.test.ts +209 -18
  645. package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
  646. package/src/scripts/codex-native-hook.ts +3638 -475
  647. package/src/scripts/codex-native-pre-post.ts +43 -12
  648. package/src/scripts/generate-native-release-manifest.ts +83 -79
  649. package/src/scripts/notify-fallback-watcher.ts +38 -38
  650. package/src/scripts/notify-hook/state-io.ts +11 -0
  651. package/src/scripts/notify-hook/team-leader-nudge.ts +32 -4
  652. package/src/scripts/notify-hook/team-worker-stop.ts +23 -4
  653. package/src/scripts/notify-hook/team-worker.ts +43 -5
  654. package/src/scripts/notify-hook/tmux-injection.ts +5 -1
  655. package/src/scripts/notify-hook.ts +83 -82
  656. package/src/scripts/postinstall-advisory.ts +67 -0
  657. package/src/scripts/postinstall.ts +1 -1
  658. package/src/scripts/smoke-packed-install.ts +446 -59
  659. package/src/scripts/sync-plugin-mirror.ts +17 -1
  660. package/src/scripts/verify-native-release-assets.ts +39 -31
  661. package/templates/AGENTS.md +1 -0
@@ -1243,9 +1243,21 @@ function commandHasPowerShellQuestionReturnPane(command: string): boolean {
1243
1243
  }
1244
1244
 
1245
1245
  function commandHasQuestionReturnPane(command: string): boolean {
1246
- if (hasInheritedQuestionReturnPaneBridge()) return true;
1247
1246
  if (commandHasPowerShellQuestionReturnPane(command)) return true;
1248
- return (tokenizeShellCommand(command) ?? []).some(isQuestionReturnPaneAssignment);
1247
+ const tokens = tokenizeShellCommand(command) ?? [];
1248
+ const localBridgeTokens = tokens.filter((token) => {
1249
+ const equalsIndex = token.indexOf('=');
1250
+ if (equalsIndex <= 0) return false;
1251
+ const name = token.slice(0, equalsIndex);
1252
+ return name === 'OMX_QUESTION_RETURN_PANE' || name === 'OMX_LEADER_PANE_ID';
1253
+ });
1254
+ if (localBridgeTokens.length > 0) {
1255
+ // A command-local bridge assignment overrides the inherited environment for the
1256
+ // invoked process, so its validity — not the inherited pane — governs the decision.
1257
+ return localBridgeTokens.every(isQuestionReturnPaneAssignment);
1258
+ }
1259
+ if (hasInheritedQuestionReturnPaneBridge()) return true;
1260
+ return tokens.some(isQuestionReturnPaneAssignment);
1249
1261
  }
1250
1262
 
1251
1263
  function commandInvokesOmxTeam(command: string): boolean {
@@ -1296,29 +1308,48 @@ function buildNativeOmxTeamPreToolUseEnforcementOutput(
1296
1308
  };
1297
1309
  }
1298
1310
 
1299
- function buildOmxQuestionPreToolUseEnforcementOutput(
1311
+ export type OmxQuestionPreToolUseClassification =
1312
+ | { kind: "not-question" }
1313
+ | { kind: "allowed" }
1314
+ | { kind: "denied"; output: Record<string, unknown> };
1315
+
1316
+ export function classifyOmxQuestionPreToolUse(
1300
1317
  command: string,
1301
1318
  payload: CodexHookPayload,
1302
- ): Record<string, unknown> | null {
1303
- if (!commandInvokesOmxQuestion(command)) return null;
1319
+ ): OmxQuestionPreToolUseClassification {
1320
+ if (!commandInvokesOmxQuestion(command)) return { kind: "not-question" };
1304
1321
 
1305
1322
  if (isNativeOutsideTmuxSurface(payload)) {
1306
1323
  return {
1307
- decision: "block",
1308
- reason: "omx question cannot be launched directly from Codex App/native outside-tmux Bash sessions.",
1309
- systemMessage: `omx question is blocked from Codex App/native outside-tmux Bash because no attached tmux pane is available. Use the native structured question tool when available, or ask exactly one concise plain-text question. Original command: ${command}`,
1324
+ kind: "denied",
1325
+ output: {
1326
+ decision: "block",
1327
+ reason: "omx question cannot be launched directly from Codex App/native outside-tmux Bash sessions.",
1328
+ systemMessage: `omx question is blocked from Codex App/native outside-tmux Bash because no attached tmux pane is available. Use the native structured question tool when available, or ask exactly one concise plain-text question. Original command: ${command}`,
1329
+ },
1310
1330
  };
1311
1331
  }
1312
1332
 
1313
- if (commandHasQuestionReturnPane(command)) return null;
1333
+ if (commandHasQuestionReturnPane(command)) return { kind: "allowed" };
1314
1334
 
1315
1335
  return {
1316
- decision: "block",
1317
- reason: "omx question Bash invocations must preserve the leader pane return target.",
1318
- systemMessage: `omx question is blocked from Bash until the command preserves the leader pane with \`OMX_QUESTION_RETURN_PANE=$TMUX_PANE\` or an explicit \`%pane\` value. Original command: ${command}`,
1336
+ kind: "denied",
1337
+ output: {
1338
+ decision: "block",
1339
+ reason: "omx question Bash invocations must preserve the leader pane return target.",
1340
+ systemMessage: `omx question is blocked from Bash until the command preserves the leader pane with \`OMX_QUESTION_RETURN_PANE=$TMUX_PANE\` or an explicit \`%pane\` value. Original command: ${command}`,
1341
+ },
1319
1342
  };
1320
1343
  }
1321
1344
 
1345
+ function buildOmxQuestionPreToolUseEnforcementOutput(
1346
+ command: string,
1347
+ payload: CodexHookPayload,
1348
+ ): Record<string, unknown> | null {
1349
+ const classification = classifyOmxQuestionPreToolUse(command, payload);
1350
+ return classification.kind === "denied" ? classification.output : null;
1351
+ }
1352
+
1322
1353
  export function buildNativePreToolUseOutput(
1323
1354
  payload: CodexHookPayload,
1324
1355
  ): Record<string, unknown> | null {
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync, writeFileSync, statSync, readdirSync } from 'node:fs';
2
+ import { createHash } from 'node:crypto';
3
+ import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
3
4
  import { join, resolve } from 'node:path';
5
+ import { inspectNativeArchive, selectNativeArchiveBinary } from '../native-assets/archive.js';
6
+ import {
7
+ nativeTargetMapping,
8
+ validateNativeReleaseManifest,
9
+ type NativeReleaseAssetPolicyInput,
10
+ } from '../native-assets/policy.js';
4
11
 
5
- function usage(): void {
12
+ function usage(): never {
6
13
  console.error('Usage: node scripts/generate-native-release-manifest.mjs --plan <path> --artifacts-dir <dir> --out <path> --release-base-url <url> [--require-products a,b]');
7
14
  process.exit(1);
8
15
  }
9
16
 
10
17
  function arg(name: string): string | undefined {
11
18
  const index = process.argv.indexOf(name);
12
- if (index === -1) return undefined;
13
- return process.argv[index + 1];
19
+ return index === -1 ? undefined : process.argv[index + 1];
14
20
  }
15
21
 
16
22
  function walk(dir: string): string[] {
@@ -18,42 +24,31 @@ function walk(dir: string): string[] {
18
24
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
19
25
  const full = join(dir, entry.name);
20
26
  if (entry.isDirectory()) files.push(...walk(full));
21
- else files.push(full);
27
+ else if (entry.isFile()) files.push(full);
22
28
  }
23
29
  return files;
24
30
  }
25
31
 
26
- function parseChecksum(raw: string): string {
27
- return String(raw).trim().split(/\s+/)[0];
32
+ function sha256(path: string): string {
33
+ return createHash('sha256').update(readFileSync(path)).digest('hex');
28
34
  }
29
35
 
30
- interface TripleMapping {
31
- platform: string;
32
- arch: string;
33
- libc?: string;
36
+ function checksum(raw: string, artifact: string): string {
37
+ const value = raw.trim().split(/\s+/)[0] || '';
38
+ if (!/^[a-f0-9]{64}$/i.test(value)) throw new Error(`invalid SHA-256 sidecar for ${artifact}`);
39
+ return value.toLowerCase();
34
40
  }
35
41
 
36
- function mapTriple(triple: string): TripleMapping | undefined {
37
- switch (triple) {
38
- case 'x86_64-unknown-linux-gnu': return { platform: 'linux', arch: 'x64', libc: 'glibc' };
39
- case 'aarch64-unknown-linux-gnu': return { platform: 'linux', arch: 'arm64', libc: 'glibc' };
40
- case 'x86_64-unknown-linux-musl': return { platform: 'linux', arch: 'x64', libc: 'musl' };
41
- case 'aarch64-unknown-linux-musl': return { platform: 'linux', arch: 'arm64', libc: 'musl' };
42
- case 'x86_64-apple-darwin': return { platform: 'darwin', arch: 'x64' };
43
- case 'aarch64-apple-darwin': return { platform: 'darwin', arch: 'arm64' };
44
- case 'x86_64-pc-windows-msvc': return { platform: 'win32', arch: 'x64' };
45
- case 'aarch64-pc-windows-msvc': return { platform: 'win32', arch: 'arm64' };
46
- default: return undefined;
42
+ function basenameIndex(files: string[]): Map<string, string> {
43
+ const result = new Map<string, string>();
44
+ for (const file of files) {
45
+ const name = file.split(/[\\/]/).at(-1)!;
46
+ if (result.has(name)) throw new Error(`duplicate artifact basename: ${name}`);
47
+ result.set(name, file);
47
48
  }
49
+ return result;
48
50
  }
49
51
 
50
- const planPath = arg('--plan');
51
- const artifactsDir = arg('--artifacts-dir');
52
- const outPath = arg('--out');
53
- const releaseBaseUrl = arg('--release-base-url');
54
- const requireProducts = (arg('--require-products') || '').split(',').map((value) => value.trim()).filter(Boolean);
55
- if (!planPath || !artifactsDir || !outPath || !releaseBaseUrl) usage();
56
-
57
52
  interface PlanArtifact {
58
53
  kind: string;
59
54
  name: string;
@@ -73,75 +68,84 @@ interface Plan {
73
68
  announcement_tag: string;
74
69
  }
75
70
 
76
- interface ManifestAsset {
77
- product: string;
78
- version: string;
79
- platform: string;
80
- arch: string;
81
- target: string;
82
- libc?: string;
83
- archive: string;
84
- binary: string;
85
- binary_path: string;
86
- sha256: string;
87
- size: number;
88
- download_url: string;
89
- }
71
+ const planPath = arg('--plan');
72
+ const artifactsDir = arg('--artifacts-dir');
73
+ const outPath = arg('--out');
74
+ const releaseBaseUrl = arg('--release-base-url');
75
+ const requestedProducts = (arg('--require-products') || '').split(',').map((value) => value.trim()).filter(Boolean);
76
+ // A product preflight denotes a full cargo-dist release. omx-runtime is released with
77
+ // that bundle but is intentionally not a runtime-hydratable product.
78
+ const requireProducts = requestedProducts.length === 0
79
+ ? []
80
+ : [...new Set([...requestedProducts, 'omx-runtime'])];
81
+ if (!planPath || !artifactsDir || !outPath || !releaseBaseUrl) usage();
90
82
 
91
- const plan = JSON.parse(readFileSync(resolve(planPath!), 'utf-8')) as Plan;
92
- const files = walk(resolve(artifactsDir!));
93
- const byName = new Map(files.map((file) => [file.split('/').pop()!, file]));
94
- const assets: ManifestAsset[] = [];
83
+ const plan = JSON.parse(readFileSync(resolve(planPath), 'utf-8')) as Plan;
84
+ if (!/^v[^\s/]+$/.test(plan.announcement_tag)) throw new Error('announcement tag must be a v-prefixed release version');
85
+ const version = plan.announcement_tag.slice(1);
86
+ if (!Array.isArray(plan.releases) || plan.releases.length === 0 || plan.releases.some((release) => release.app_version !== version)) {
87
+ throw new Error(`release versions must exactly match announcement tag ${plan.announcement_tag}`);
88
+ }
95
89
 
90
+ const byName = basenameIndex(walk(resolve(artifactsDir)));
91
+ const assets: NativeReleaseAssetPolicyInput[] = [];
96
92
  for (const artifact of Object.values(plan.artifacts)) {
97
93
  if (artifact.kind !== 'executable-zip') continue;
98
- const triple = artifact.target_triples?.[0];
99
- const mapped = triple ? mapTriple(triple) : undefined;
100
- if (!mapped) continue;
101
- const executable = (artifact.assets || []).find((asset) => asset.kind === 'executable');
102
- if (!executable) continue;
94
+ if (!Array.isArray(artifact.target_triples) || artifact.target_triples.length !== 1) {
95
+ throw new Error(`expected exactly one target triple for ${artifact.name}`);
96
+ }
97
+ const target = artifact.target_triples[0]!;
98
+ const mapping = nativeTargetMapping(target);
99
+ if (!mapping) throw new Error(`unsupported native target ${target}`);
100
+ if (!/\.(?:tar\.xz|tar\.gz|zip)$/i.test(artifact.name)) throw new Error(`unsupported native archive format: ${artifact.name}`);
101
+ const executable = artifact.assets?.filter((asset) => asset.kind === 'executable') ?? [];
102
+ if (executable.length !== 1) throw new Error(`expected exactly one executable for ${artifact.name}`);
103
+ const binary = executable[0]!;
103
104
  const archivePath = byName.get(artifact.name);
104
105
  const checksumPath = byName.get(artifact.checksum);
105
- if (!archivePath || !checksumPath) {
106
- throw new Error(`missing artifact files for ${artifact.name}`);
107
- }
108
-
109
- const release = plan.releases.find((item) => item.app_name === executable.name || item.app_name === executable.id?.split('-exe-')[0]);
110
- const version = release?.app_version || plan.announcement_tag.replace(/^v/, '');
106
+ if (!archivePath || !checksumPath) throw new Error(`missing artifact files for ${artifact.name}`);
107
+ if (statSync(archivePath).size <= 0 || statSync(checksumPath).size <= 0) throw new Error(`empty artifact file for ${artifact.name}`);
108
+ const expectedSha256 = checksum(readFileSync(checksumPath, 'utf-8'), artifact.name);
109
+ if (sha256(archivePath) !== expectedSha256) throw new Error(`checksum mismatch for ${artifact.name}`);
110
+ const archiveEntries = await inspectNativeArchive(archivePath);
111
+ selectNativeArchiveBinary(archiveEntries, binary.path);
112
+ const release = plan.releases.find((item) => item.app_name === binary.name || item.app_name === binary.id?.split('-exe-')[0]);
113
+ if (!release || release.app_version !== version) throw new Error(`missing coherent release metadata for ${artifact.name}`);
111
114
  assets.push({
112
- product: executable.name,
115
+ product: release.app_name,
113
116
  version,
114
- platform: mapped.platform,
115
- arch: mapped.arch,
116
- target: triple!,
117
- ...(mapped.libc ? { libc: mapped.libc } : {}),
117
+ platform: mapping.platform,
118
+ arch: mapping.arch,
119
+ target,
120
+ ...(mapping.libc ? { libc: mapping.libc } : {}),
118
121
  archive: artifact.name,
119
- binary: executable.name,
120
- binary_path: executable.path,
121
- sha256: parseChecksum(readFileSync(checksumPath, 'utf-8')),
122
+ binary: release.app_name,
123
+ binary_path: binary.path,
124
+ sha256: expectedSha256,
122
125
  size: statSync(archivePath).size,
123
- download_url: `${releaseBaseUrl!.replace(/\/$/, '')}/${artifact.name}`,
126
+ download_url: `${releaseBaseUrl.replace(/\/$/, '')}/${artifact.name}`,
124
127
  });
125
128
  }
126
129
 
127
130
  const manifest = {
128
131
  manifest_version: 1,
129
- version: plan.announcement_tag.replace(/^v/, ''),
132
+ version,
130
133
  tag: plan.announcement_tag,
131
134
  generated_at: new Date().toISOString(),
132
135
  assets: assets.sort((a, b) => {
133
- const keyCompare = `${a.product}-${a.platform}-${a.arch}`.localeCompare(`${b.product}-${b.platform}-${b.arch}`);
134
- if (keyCompare !== 0) return keyCompare;
135
- const libcOrder: Record<string, number> = { musl: 0, glibc: 1 };
136
- const libcCompare = (libcOrder[a.libc ?? ''] ?? 2) - (libcOrder[b.libc ?? ''] ?? 2);
137
- if (libcCompare !== 0) return libcCompare;
138
- return a.archive.localeCompare(b.archive);
136
+ const libcRank = (asset: NativeReleaseAssetPolicyInput): number => asset.libc === 'musl' ? 0 : asset.libc === 'glibc' ? 1 : 2;
137
+ return a.product.localeCompare(b.product)
138
+ || a.platform.localeCompare(b.platform)
139
+ || a.arch.localeCompare(b.arch)
140
+ || libcRank(a) - libcRank(b)
141
+ || a.archive.localeCompare(b.archive);
139
142
  }),
140
143
  };
144
+ if (manifest.assets.length === 0) throw new Error('release manifest must declare at least one native archive');
145
+ validateNativeReleaseManifest(manifest);
146
+ if (manifest.tag !== `v${manifest.version}`) throw new Error('manifest tag/version mismatch');
141
147
  for (const product of requireProducts) {
142
- if (!manifest.assets.some((asset) => asset.product === product)) {
143
- throw new Error(`missing required product in release manifest: ${product}`);
144
- }
148
+ if (!manifest.assets.some((asset) => asset.product === product)) throw new Error(`missing required product in release manifest: ${product}`);
145
149
  }
146
- writeFileSync(resolve(outPath!), `${JSON.stringify(manifest, null, 2)}\n`);
147
- console.log(resolve(outPath!));
150
+ writeFileSync(resolve(outPath), `${JSON.stringify(manifest, null, 2)}\n`);
151
+ console.log(resolve(outPath));
@@ -19,14 +19,13 @@ import {
19
19
  import {
20
20
  readScopedJsonIfExists,
21
21
  } from './notify-hook/state-io.js';
22
- import { checkPaneReadyForTeamSendKeys } from './notify-hook/team-tmux-guard.js';
23
22
  import {
24
23
  checkWorkerPanesAlive,
25
24
  isLeaderStale,
26
25
  maybeNudgeTeamLeader,
27
26
  resolveLeaderStalenessThresholdMs,
28
27
  } from './notify-hook/team-leader-nudge.js';
29
- import { DEFAULT_MARKER } from './tmux-hook-engine.js';
28
+ import { DEFAULT_MARKER, isPaneRunningShell } from './tmux-hook-engine.js';
30
29
  import { isTerminalPhase } from './notify-hook/utils.js';
31
30
  import { isSessionStale, isSessionStateAuthoritativeForCwd, readSessionState } from '../hooks/session.js';
32
31
  import {
@@ -39,7 +38,6 @@ import { validateSessionId } from '../mcp/state-paths.js';
39
38
  import { TEAM_NAME_SAFE_PATTERN } from '../team/contracts.js';
40
39
  import { shouldContinueRun } from '../runtime/run-loop.js';
41
40
  import { deliverNotifyFallback, compactNotifyFallbackDeliveries, NOTIFY_FALLBACK_LEASE_MS } from './notify-fallback-delivery.js';
42
- import { readExactPaneProofSync } from '../team/exact-pane.js';
43
41
  import { OMX_RALPH_PANE_OWNER_OPTION } from '../state/mode-state-context.js';
44
42
 
45
43
  function argValue(name: string, fallback = ''): string {
@@ -196,6 +194,7 @@ interface RalphContinueSteerState {
196
194
  state_path: string;
197
195
  pane_id: string;
198
196
  pane_current_command: string;
197
+ pane_start_command: string;
199
198
  current_phase: string;
200
199
  subagent_session_id: string;
201
200
  active_subagent_thread_ids: string[];
@@ -345,6 +344,7 @@ let lastRalphContinueSteer: RalphContinueSteerState = {
345
344
  state_path: '',
346
345
  pane_id: '',
347
346
  pane_current_command: '',
347
+ pane_start_command: '',
348
348
  current_phase: '',
349
349
  subagent_session_id: '',
350
350
  active_subagent_thread_ids: [],
@@ -509,6 +509,7 @@ function normalizeRalphContinueSteerState(raw: Record<string, unknown> | null |
509
509
  state_path: safeString(raw.state_path),
510
510
  pane_id: safeString(raw.pane_id),
511
511
  pane_current_command: safeString(raw.pane_current_command),
512
+ pane_start_command: safeString(raw.pane_start_command),
512
513
  current_phase: safeString(raw.current_phase),
513
514
  subagent_session_id: safeString(raw.subagent_session_id),
514
515
  active_subagent_thread_ids: Array.isArray(raw.active_subagent_thread_ids)
@@ -780,45 +781,54 @@ interface RalphContinuePaneBinding {
780
781
  paneId: string;
781
782
  panePid: number;
782
783
  sessionName: string;
784
+ sessionId: string;
785
+ windowId: string;
783
786
  paneOwnerId: string;
787
+ paneCurrentCommand: string;
788
+ paneStartCommand: string;
789
+ }
790
+
791
+ function isSafeRalphAuthorityValue(value: string): boolean {
792
+ return /^[A-Za-z0-9_./:+@%=-]+(?: [A-Za-z0-9_./:+@%=-]+)*$/.test(value);
784
793
  }
785
794
 
786
795
  function parseRalphContinuePaneBinding(state: Record<string, unknown> | null): RalphContinuePaneBinding | null {
787
796
  const paneId = safeString(state?.tmux_pane_id).trim();
788
797
  const panePid = parsePositivePid(state?.tmux_pane_pid);
789
798
  const sessionName = safeString(state?.tmux_session_name).trim();
799
+ const sessionId = safeString(state?.tmux_session_id).trim();
800
+ const windowId = safeString(state?.tmux_window_id).trim();
790
801
  const paneOwnerId = safeString(state?.tmux_pane_owner_id).trim();
791
- if (!/^%[0-9]+$/.test(paneId) || panePid === null || !sessionName || !paneOwnerId) return null;
802
+ const paneCurrentCommand = safeString(state?.tmux_pane_current_command).trim();
803
+ const paneStartCommand = safeString(state?.tmux_pane_start_command).trim();
804
+ if (!/^%[0-9]+$/.test(paneId) || panePid === null || !sessionName || !/^\$[0-9]+$/.test(sessionId)
805
+ || !/^@[0-9]+$/.test(windowId) || !paneOwnerId) return null;
806
+ if (!isSafeRalphAuthorityValue(sessionName) || !isSafeRalphAuthorityValue(paneOwnerId)
807
+ || !isSafeRalphAuthorityValue(paneCurrentCommand) || !isSafeRalphAuthorityValue(paneStartCommand)
808
+ || isPaneRunningShell(paneCurrentCommand)) return null;
792
809
  if (paneOwnerId.startsWith('team:')) return null;
793
- return { paneId, panePid, sessionName, paneOwnerId };
810
+ return { paneId, panePid, sessionName, sessionId, windowId, paneOwnerId, paneCurrentCommand, paneStartCommand };
794
811
  }
795
812
 
796
- function requireFrozenRalphPaneBinding(binding: RalphContinuePaneBinding): void {
797
- const initialProof = readExactPaneProofSync(binding.paneId);
798
- if (initialProof.status !== 'live' || initialProof.pid !== binding.panePid) {
799
- throw new Error(`persisted Ralph pane identity unavailable: ${binding.paneId}`);
800
- }
801
- const session = spawnPlatformCommandSync('tmux', ['display-message', '-p', '-t', binding.paneId, '#S'], { encoding: 'utf-8' }).result;
802
- if (session.error || session.status !== 0 || safeString(session.stdout).trim() !== binding.sessionName) {
803
- throw new Error(`persisted Ralph pane session changed: ${binding.paneId}`);
804
- }
805
- const owner = spawnPlatformCommandSync('tmux', ['show-option', '-qv', '-p', '-t', binding.paneId, OMX_RALPH_PANE_OWNER_OPTION], { encoding: 'utf-8' }).result;
806
- if (owner.error || owner.status !== 0 || safeString(owner.stdout).trim() !== binding.paneOwnerId) {
807
- throw new Error(`persisted Ralph pane owner changed: ${binding.paneId}`);
808
- }
809
- const finalProof = readExactPaneProofSync(binding.paneId);
810
- if (finalProof.status !== 'live' || finalProof.pid !== binding.panePid) {
811
- throw new Error(`persisted Ralph pane identity changed: ${binding.paneId}`);
812
- }
813
+ function ralphInputAuthorityCondition(binding: RalphContinuePaneBinding): string {
814
+ return `#{&&:#{==:#{pane_id},${binding.paneId}},#{&&:#{==:#{pane_dead},0},#{&&:#{==:#{pane_pid},${binding.panePid}},#{&&:#{==:#{session_name},${binding.sessionName}},#{&&:#{==:#{session_id},${binding.sessionId}},#{&&:#{==:#{window_id},${binding.windowId}},#{&&:#{==:#{${OMX_RALPH_PANE_OWNER_OPTION}},${binding.paneOwnerId}},#{&&:#{==:#{pane_current_command},${binding.paneCurrentCommand}},#{==:#{pane_start_command},${binding.paneStartCommand}}}}}}}}}`;
813
815
  }
814
816
 
815
817
  async function emitRalphContinueSteer(binding: RalphContinuePaneBinding, message: string): Promise<void> {
816
818
  const markedText = `${message} ${DEFAULT_MARKER}`;
817
819
  const sendKeys = (args: string[], failure: string): void => {
818
- requireFrozenRalphPaneBinding(binding);
819
- const { result } = spawnPlatformCommandSync('tmux', args, { encoding: 'utf-8' });
820
+ const receipt = `__omx_ralph_input_${Math.random().toString(36).slice(2)}__`;
821
+ const success = `${args.map((arg) => `'${arg.replace(/'/g, "'\\\"'\\\"'")}'`).join(' ')} \\; display-message -p ${receipt}`;
822
+ const denied = 'display-message -p __omx_ralph_input_denied__';
823
+ const { result } = spawnPlatformCommandSync(
824
+ 'tmux',
825
+ ['if-shell', '-F', '-t', binding.paneId, ralphInputAuthorityCondition(binding), success, denied],
826
+ { encoding: 'utf-8' },
827
+ );
820
828
  if (result.error) throw new Error(result.error.message);
821
- if (result.status !== 0) throw new Error((result.stderr || result.stdout || '').trim() || failure);
829
+ if (result.status !== 0 || safeString(result.stdout).trim() !== receipt) {
830
+ throw new Error((result.stderr || result.stdout || '').trim() || failure);
831
+ }
822
832
  };
823
833
  sendKeys(['send-keys', '-t', binding.paneId, '-l', markedText], 'tmux send-keys failed');
824
834
  await sleep(100);
@@ -1126,6 +1136,7 @@ async function runRalphContinueSteerTick(): Promise<void> {
1126
1136
  state_path: activeRalph.path,
1127
1137
  pane_id: activePaneId,
1128
1138
  pane_current_command: '',
1139
+ pane_start_command: '',
1129
1140
  subagent_session_id: safeString(activeRalph.state?.owner_codex_session_id).trim(),
1130
1141
  active_subagent_thread_ids: [],
1131
1142
  shared_timestamp_path: ralphSteerTimestampPath,
@@ -1177,19 +1188,8 @@ async function runRalphContinueSteerTick(): Promise<void> {
1177
1188
  return { sent: false, skipped: true };
1178
1189
  }
1179
1190
  lastRalphContinueSteer.pane_id = binding.paneId;
1180
- try {
1181
- requireFrozenRalphPaneBinding(binding);
1182
- } catch (error) {
1183
- lastRalphContinueSteer.last_reason = 'pane_binding_changed';
1184
- lastRalphContinueSteer.last_error = error instanceof Error ? error.message : safeString(error);
1185
- return { sent: false, skipped: true };
1186
- }
1187
- const paneGuard = await checkPaneReadyForTeamSendKeys(binding.paneId, binding.paneId);
1188
- lastRalphContinueSteer.pane_current_command = paneGuard.paneCurrentCommand || '';
1189
- if (!paneGuard.ok) {
1190
- lastRalphContinueSteer.last_reason = paneGuard.reason || 'pane_guard_blocked';
1191
- return { sent: false, skipped: true };
1192
- }
1191
+ lastRalphContinueSteer.pane_current_command = binding.paneCurrentCommand;
1192
+ lastRalphContinueSteer.pane_start_command = binding.paneStartCommand;
1193
1193
  await emitRalphContinueSteer(binding, RALPH_CONTINUE_TEXT);
1194
1194
  await writeRalphSteerTimestamp(nowIso);
1195
1195
  lastRalphContinueSteer.last_sent_at = nowIso;
@@ -6,6 +6,7 @@ import { mkdir, readFile, readdir, stat, writeFile } from 'fs/promises';
6
6
  import { dirname, join } from 'path';
7
7
  import { validateSessionId } from '../../mcp/state-paths.js';
8
8
  import { asNumber, safeString } from './utils.js';
9
+ import { SKILL_ACTIVE_STATE_FILE, writeSkillActiveStateCopiesForStateDir } from '../../state/skill-active.js';
9
10
 
10
11
 
11
12
  export { readdir };
@@ -223,6 +224,16 @@ export async function writeScopedJson(
223
224
  explicitSessionId: string | undefined,
224
225
  value: unknown,
225
226
  ): Promise<void> {
227
+ if (fileName === SKILL_ACTIVE_STATE_FILE) {
228
+ await writeSkillActiveStateCopiesForStateDir(
229
+ baseStateDir,
230
+ value as Record<string, unknown>,
231
+ explicitSessionId,
232
+ undefined,
233
+ { sessionOnlyWhenRootMissing: Boolean(explicitSessionId) },
234
+ );
235
+ return;
236
+ }
226
237
  const targetPath = await getScopedStatePath(baseStateDir, fileName, explicitSessionId);
227
238
  await mkdir(dirname(targetPath), { recursive: true });
228
239
  await writeFile(targetPath, JSON.stringify(value, null, 2));
@@ -24,6 +24,7 @@ import { readLatestTeamProgressEvidenceMs } from '../../team/progress-evidence.j
24
24
  import { validateSessionId } from '../../mcp/state-paths.js';
25
25
  import { TEAM_NAME_SAFE_PATTERN } from '../../team/contracts.js';
26
26
  import { isDeepInterviewStateActive } from './auto-nudge.js';
27
+ import { registerTeamNotice, releaseTeamNoticeWake } from '../../team/notice-ledger.js';
27
28
  const LEADER_PANE_MISSING_NO_INJECTION_REASON = 'leader_pane_missing_no_injection';
28
29
  const LEADER_PANE_SHELL_NO_INJECTION_REASON = 'leader_pane_shell_no_injection';
29
30
  const TEAM_SHUTDOWN_NO_INJECTION_REASON = 'team_state_gone_or_shutdown';
@@ -1043,8 +1044,16 @@ export async function maybeNudgeTeamLeader({
1043
1044
  await recordShutdownSuppression(orchestrationIntent);
1044
1045
  continue;
1045
1046
  }
1046
- const capped = text.length > 180 ? `${text.slice(0, 177)}...` : text;
1047
- const markedText = `${capped} ${DEFAULT_MARKER}`;
1047
+ const noticeClass = nudgeReason === 'all_workers_idle'
1048
+ || nudgeReason === 'done_waiting_on_leader'
1049
+ || nudgeReason === 'stuck_waiting_on_leader'
1050
+ ? 'all_idle'
1051
+ : nudgeReason.includes('stale')
1052
+ ? 'leader_stale'
1053
+ : 'mailbox';
1054
+ const noticeGeneration = noticeClass === 'mailbox' && newestId
1055
+ ? newestId
1056
+ : `${nudgeReason}:${progressSnapshot.signature}:${prevIdleAtIso || prevAtIso || 'initial'}`;
1048
1057
 
1049
1058
  if (!tmuxTarget) {
1050
1059
  if (!(await teamStateAllowsLeaderNudge(stateDir, teamName))) {
@@ -1148,7 +1157,7 @@ export async function maybeNudgeTeamLeader({
1148
1157
  continue;
1149
1158
  }
1150
1159
 
1151
- if (paneAlreadyShowsVisibleLeaderState(paneGuard.paneCapture, capped)) {
1160
+ if (paneAlreadyShowsVisibleLeaderState(paneGuard.paneCapture, text)) {
1152
1161
  if (!(await teamStateAllowsLeaderNudge(stateDir, teamName))) {
1153
1162
  await recordShutdownSuppression(orchestrationIntent);
1154
1163
  continue;
@@ -1194,11 +1203,26 @@ export async function maybeNudgeTeamLeader({
1194
1203
  await recordShutdownSuppression(orchestrationIntent);
1195
1204
  continue;
1196
1205
  }
1197
-
1206
+ let queuedNoticeRegistration = null;
1198
1207
  try {
1199
1208
  const leaderHasActiveTask = paneHasActiveTask(paneGuard.paneCapture);
1200
1209
  let deliveryMode = 'sent';
1210
+ let markedText = `${text.length > 180 ? `${text.slice(0, 177)}...` : text} ${DEFAULT_MARKER}`;
1201
1211
  if (leaderHasActiveTask) {
1212
+ const noticeRegistration = await registerTeamNotice({
1213
+ stateRoot: stateDir,
1214
+ targetId: tmuxPaneOwnerId,
1215
+ teamName,
1216
+ noticeClass,
1217
+ generation: noticeGeneration,
1218
+ source: { kind: 'leader_nudge', detail: nudgeReason },
1219
+ }).catch(() => null);
1220
+ if (!noticeRegistration?.queued || !noticeRegistration.prompt) {
1221
+ await persistLeaderNudgeBookkeeping({ orchestrationIntent, recordLastNudged: true });
1222
+ continue;
1223
+ }
1224
+ markedText = `${noticeRegistration.prompt} ${DEFAULT_MARKER}`;
1225
+ queuedNoticeRegistration = noticeRegistration;
1202
1226
  const sendResult = await sendPaneInput({
1203
1227
  paneTarget: tmuxTarget,
1204
1228
  prompt: markedText,
@@ -1214,6 +1238,7 @@ export async function maybeNudgeTeamLeader({
1214
1238
  throw new Error(sendResult.error || sendResult.reason);
1215
1239
  }
1216
1240
  deliveryMode = 'queued';
1241
+ queuedNoticeRegistration = null;
1217
1242
  } else {
1218
1243
  const sendResult = await sendPaneInput({
1219
1244
  paneTarget: tmuxTarget,
@@ -1266,6 +1291,9 @@ export async function maybeNudgeTeamLeader({
1266
1291
  orchestration_intent: orchestrationIntent,
1267
1292
  }).catch(() => {});
1268
1293
  } catch (err) {
1294
+ if (queuedNoticeRegistration?.targetKey && queuedNoticeRegistration?.wakeId) {
1295
+ await releaseTeamNoticeWake(stateDir, queuedNoticeRegistration.targetKey, queuedNoticeRegistration.wakeId).catch(() => {});
1296
+ }
1269
1297
  if (!(await teamStateAllowsLeaderNudge(stateDir, teamName))) {
1270
1298
  await recordShutdownSuppression(orchestrationIntent);
1271
1299
  continue;
@@ -16,6 +16,7 @@ import { readJsonIfExists } from './state-io.js';
16
16
  import { logTmuxHookEvent } from './log.js';
17
17
  import { evaluatePaneInjectionReadiness, normalizeExactPaneId, sendPaneInput } from './team-tmux-guard.js';
18
18
  import { readTeamWorkersForIdleCheck } from './team-worker.js';
19
+ import { registerTeamNotice, releaseTeamNoticeWake } from '../../team/notice-ledger.js';
19
20
 
20
21
  const STOP_NUDGE_COOLDOWN_MS = 30_000;
21
22
  const SOURCE_TYPE = 'worker_stop';
@@ -249,6 +250,7 @@ export async function maybeNudgeLeaderForAllowedWorkerStop({
249
250
  let tmuxSession = '';
250
251
  let leaderPaneId = '';
251
252
  let recordedShutdownSuppression = false;
253
+ let queuedNoticeRegistration = null;
252
254
  const recordShutdownSuppressionOnce = async () => {
253
255
  if (recordedShutdownSuppression) return;
254
256
  recordedShutdownSuppression = true;
@@ -356,10 +358,23 @@ export async function maybeNudgeLeaderForAllowedWorkerStop({
356
358
  return { ok: true, result: TEAM_SHUTDOWN_NO_INJECTION_REASON };
357
359
  }
358
360
 
359
- const prompt =
360
- `[OMX] ${workerName} native Stop allowed. `
361
- + `Run \`omx team status ${teamName}\`, read worker messages/results, then assign next task, reconcile completion, or shut down. `
362
- + DEFAULT_MARKER;
361
+ const leaderBusy = paneHasActiveTask(paneGuard.paneCapture);
362
+ let prompt = `[OMX] ${workerName} native Stop allowed. Run \`omx team status ${teamName}\`, read worker messages/results, then assign next task, reconcile completion, or shut down. ${DEFAULT_MARKER}`;
363
+ if (leaderBusy) {
364
+ const noticeRegistration = await registerTeamNotice({
365
+ stateRoot: stateDir,
366
+ targetId: leaderPaneOwnerId,
367
+ teamName,
368
+ noticeClass: 'worker_stop',
369
+ generation: `${nowIso}:${workerName}`,
370
+ source: { kind: SOURCE_TYPE, detail: workerName },
371
+ }).catch(() => null);
372
+ if (!noticeRegistration?.queued || !noticeRegistration.prompt) {
373
+ return { ok: true, result: 'coalesced' };
374
+ }
375
+ prompt = `${noticeRegistration.prompt} ${DEFAULT_MARKER}`;
376
+ queuedNoticeRegistration = noticeRegistration;
377
+ }
363
378
 
364
379
  const leaderHasActiveTask = paneHasActiveTask(paneGuard.paneCapture);
365
380
  const sendResult = await sendPaneInput({
@@ -373,6 +388,7 @@ export async function maybeNudgeLeaderForAllowedWorkerStop({
373
388
  expectedHudPaneId: teamInfo.hudPaneId,
374
389
  });
375
390
  if (!sendResult.ok) throw new Error(sendResult.error || sendResult.reason || 'send_failed');
391
+ queuedNoticeRegistration = null;
376
392
  const deliveryMode = leaderHasActiveTask ? 'steered' : 'sent';
377
393
 
378
394
  const deliveryState = {
@@ -418,6 +434,9 @@ export async function maybeNudgeLeaderForAllowedWorkerStop({
418
434
  }).catch(() => {});
419
435
  return { ok: true, result: deliveryMode };
420
436
  } catch (err) {
437
+ if (queuedNoticeRegistration?.targetKey && queuedNoticeRegistration?.wakeId) {
438
+ await releaseTeamNoticeWake(stateDir, queuedNoticeRegistration.targetKey, queuedNoticeRegistration.wakeId).catch(() => {});
439
+ }
421
440
  if (!(await teamStateAllowsWorkerStopNudge(stateDir, teamName))) {
422
441
  await recordShutdownSuppressionOnce();
423
442
  return { ok: true, result: TEAM_SHUTDOWN_NO_INJECTION_REASON };