oh-my-codex 0.21.0 → 0.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/Cargo.toml +1 -1
  2. package/README.md +4 -2
  3. package/dist/cli/__tests__/detached-launch-diagnostics-3578.test.d.ts +2 -0
  4. package/dist/cli/__tests__/detached-launch-diagnostics-3578.test.d.ts.map +1 -0
  5. package/dist/cli/__tests__/detached-launch-diagnostics-3578.test.js +592 -0
  6. package/dist/cli/__tests__/detached-launch-diagnostics-3578.test.js.map +1 -0
  7. package/dist/cli/__tests__/detached-leader-teardown.test.js +270 -33
  8. package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -1
  9. package/dist/cli/__tests__/doctor-warning-copy.test.js +133 -5
  10. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  11. package/dist/cli/__tests__/index.test.js +543 -2
  12. package/dist/cli/__tests__/index.test.js.map +1 -1
  13. package/dist/cli/__tests__/issue-windows-cancel-identity.test.d.ts +2 -0
  14. package/dist/cli/__tests__/issue-windows-cancel-identity.test.d.ts.map +1 -0
  15. package/dist/cli/__tests__/issue-windows-cancel-identity.test.js +17 -0
  16. package/dist/cli/__tests__/issue-windows-cancel-identity.test.js.map +1 -0
  17. package/dist/cli/__tests__/launch-fallback.test.js +15 -3
  18. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  19. package/dist/cli/__tests__/package-bin-contract.test.js +20 -0
  20. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  21. package/dist/cli/__tests__/plugin-cache-stale-lock.test.d.ts +2 -0
  22. package/dist/cli/__tests__/plugin-cache-stale-lock.test.d.ts.map +1 -0
  23. package/dist/cli/__tests__/plugin-cache-stale-lock.test.js +76 -0
  24. package/dist/cli/__tests__/plugin-cache-stale-lock.test.js.map +1 -0
  25. package/dist/cli/__tests__/plugin-cache-symlink-provenance-3552.test.d.ts +2 -0
  26. package/dist/cli/__tests__/plugin-cache-symlink-provenance-3552.test.d.ts.map +1 -0
  27. package/dist/cli/__tests__/plugin-cache-symlink-provenance-3552.test.js +1662 -0
  28. package/dist/cli/__tests__/plugin-cache-symlink-provenance-3552.test.js.map +1 -0
  29. package/dist/cli/__tests__/plugin-launcher-provenance-3558.test.d.ts +2 -0
  30. package/dist/cli/__tests__/plugin-launcher-provenance-3558.test.d.ts.map +1 -0
  31. package/dist/cli/__tests__/plugin-launcher-provenance-3558.test.js +522 -0
  32. package/dist/cli/__tests__/plugin-launcher-provenance-3558.test.js.map +1 -0
  33. package/dist/cli/__tests__/ralplan-advisory.test.d.ts +2 -0
  34. package/dist/cli/__tests__/ralplan-advisory.test.d.ts.map +1 -0
  35. package/dist/cli/__tests__/ralplan-advisory.test.js +301 -0
  36. package/dist/cli/__tests__/ralplan-advisory.test.js.map +1 -0
  37. package/dist/cli/__tests__/ralplan.test.js +39 -0
  38. package/dist/cli/__tests__/ralplan.test.js.map +1 -1
  39. package/dist/cli/__tests__/resume.test.js +81 -6
  40. package/dist/cli/__tests__/resume.test.js.map +1 -1
  41. package/dist/cli/__tests__/session-scoped-runtime.test.js +423 -4
  42. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  43. package/dist/cli/__tests__/setup-install-mode.test.js +60 -3
  44. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  45. package/dist/cli/__tests__/setup-refresh.test.js +9 -0
  46. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  47. package/dist/cli/__tests__/sparkshell-cli.test.js +4 -0
  48. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  49. package/dist/cli/__tests__/ultragoal.test.js +71 -0
  50. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  51. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +30 -4
  52. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  53. package/dist/cli/doctor.d.ts.map +1 -1
  54. package/dist/cli/doctor.js +57 -8
  55. package/dist/cli/doctor.js.map +1 -1
  56. package/dist/cli/index.d.ts +113 -7
  57. package/dist/cli/index.d.ts.map +1 -1
  58. package/dist/cli/index.js +1850 -185
  59. package/dist/cli/index.js.map +1 -1
  60. package/dist/cli/native-assets.d.ts +2 -1
  61. package/dist/cli/native-assets.d.ts.map +1 -1
  62. package/dist/cli/native-assets.js +7 -7
  63. package/dist/cli/native-assets.js.map +1 -1
  64. package/dist/cli/plugin-marketplace.d.ts +89 -4
  65. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  66. package/dist/cli/plugin-marketplace.js +2135 -118
  67. package/dist/cli/plugin-marketplace.js.map +1 -1
  68. package/dist/cli/ralplan.d.ts +2 -1
  69. package/dist/cli/ralplan.d.ts.map +1 -1
  70. package/dist/cli/ralplan.js +149 -9
  71. package/dist/cli/ralplan.js.map +1 -1
  72. package/dist/cli/setup.d.ts.map +1 -1
  73. package/dist/cli/setup.js +7 -1
  74. package/dist/cli/setup.js.map +1 -1
  75. package/dist/cli/sparkshell.d.ts.map +1 -1
  76. package/dist/cli/sparkshell.js +9 -10
  77. package/dist/cli/sparkshell.js.map +1 -1
  78. package/dist/cli/update-worker.js +9 -0
  79. package/dist/cli/update-worker.js.map +1 -1
  80. package/dist/cli/update.d.ts +1 -0
  81. package/dist/cli/update.d.ts.map +1 -1
  82. package/dist/cli/update.js +9 -0
  83. package/dist/cli/update.js.map +1 -1
  84. package/dist/config/__tests__/generator-idempotent.test.js +118 -0
  85. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  86. package/dist/config/generator.d.ts.map +1 -1
  87. package/dist/config/generator.js +74 -4
  88. package/dist/config/generator.js.map +1 -1
  89. package/dist/hooks/__tests__/keyword-detector.test.js +74 -0
  90. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  91. package/dist/hooks/__tests__/ralplan-advisory-keyword.test.d.ts +2 -0
  92. package/dist/hooks/__tests__/ralplan-advisory-keyword.test.d.ts.map +1 -0
  93. package/dist/hooks/__tests__/ralplan-advisory-keyword.test.js +250 -0
  94. package/dist/hooks/__tests__/ralplan-advisory-keyword.test.js.map +1 -0
  95. package/dist/hooks/__tests__/session.test.js +10 -1
  96. package/dist/hooks/__tests__/session.test.js.map +1 -1
  97. package/dist/hooks/keyword-detector.d.ts +8 -1
  98. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  99. package/dist/hooks/keyword-detector.js +130 -9
  100. package/dist/hooks/keyword-detector.js.map +1 -1
  101. package/dist/hooks/session.d.ts +5 -0
  102. package/dist/hooks/session.d.ts.map +1 -1
  103. package/dist/hooks/session.js +17 -3
  104. package/dist/hooks/session.js.map +1 -1
  105. package/dist/hud/__tests__/index.test.js +16 -1
  106. package/dist/hud/__tests__/index.test.js.map +1 -1
  107. package/dist/hud/__tests__/reconcile.test.js +134 -7
  108. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  109. package/dist/hud/__tests__/render.test.js +57 -0
  110. package/dist/hud/__tests__/render.test.js.map +1 -1
  111. package/dist/hud/__tests__/session-attached.test.d.ts +2 -0
  112. package/dist/hud/__tests__/session-attached.test.d.ts.map +1 -0
  113. package/dist/hud/__tests__/session-attached.test.js +82 -0
  114. package/dist/hud/__tests__/session-attached.test.js.map +1 -0
  115. package/dist/hud/__tests__/state.test.js +94 -2
  116. package/dist/hud/__tests__/state.test.js.map +1 -1
  117. package/dist/hud/__tests__/tmux-split-realtmux.test.js +169 -2
  118. package/dist/hud/__tests__/tmux-split-realtmux.test.js.map +1 -1
  119. package/dist/hud/__tests__/tmux.test.js +104 -22
  120. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  121. package/dist/hud/__tests__/types.test.js +9 -0
  122. package/dist/hud/__tests__/types.test.js.map +1 -1
  123. package/dist/hud/__tests__/watch-detached.test.d.ts +2 -0
  124. package/dist/hud/__tests__/watch-detached.test.d.ts.map +1 -0
  125. package/dist/hud/__tests__/watch-detached.test.js +383 -0
  126. package/dist/hud/__tests__/watch-detached.test.js.map +1 -0
  127. package/dist/hud/__tests__/watch-realtmux.test.d.ts +2 -0
  128. package/dist/hud/__tests__/watch-realtmux.test.d.ts.map +1 -0
  129. package/dist/hud/__tests__/watch-realtmux.test.js +322 -0
  130. package/dist/hud/__tests__/watch-realtmux.test.js.map +1 -0
  131. package/dist/hud/index.d.ts +3 -0
  132. package/dist/hud/index.d.ts.map +1 -1
  133. package/dist/hud/index.js +98 -20
  134. package/dist/hud/index.js.map +1 -1
  135. package/dist/hud/reconcile.d.ts.map +1 -1
  136. package/dist/hud/reconcile.js +68 -24
  137. package/dist/hud/reconcile.js.map +1 -1
  138. package/dist/hud/render.d.ts.map +1 -1
  139. package/dist/hud/render.js +20 -0
  140. package/dist/hud/render.js.map +1 -1
  141. package/dist/hud/session-attached.d.ts +15 -0
  142. package/dist/hud/session-attached.d.ts.map +1 -0
  143. package/dist/hud/session-attached.js +47 -0
  144. package/dist/hud/session-attached.js.map +1 -0
  145. package/dist/hud/state.d.ts +9 -1
  146. package/dist/hud/state.d.ts.map +1 -1
  147. package/dist/hud/state.js +140 -3
  148. package/dist/hud/state.js.map +1 -1
  149. package/dist/hud/tmux.d.ts +4 -0
  150. package/dist/hud/tmux.d.ts.map +1 -1
  151. package/dist/hud/tmux.js +86 -23
  152. package/dist/hud/tmux.js.map +1 -1
  153. package/dist/hud/types.d.ts +20 -0
  154. package/dist/hud/types.d.ts.map +1 -1
  155. package/dist/hud/types.js +3 -0
  156. package/dist/hud/types.js.map +1 -1
  157. package/dist/modes/base.d.ts +15 -2
  158. package/dist/modes/base.d.ts.map +1 -1
  159. package/dist/modes/base.js +105 -16
  160. package/dist/modes/base.js.map +1 -1
  161. package/dist/question/autopilot-wait.js +2 -2
  162. package/dist/question/autopilot-wait.js.map +1 -1
  163. package/dist/question/deep-interview.js +2 -2
  164. package/dist/question/deep-interview.js.map +1 -1
  165. package/dist/ralplan/__tests__/advisory-activation.test.d.ts +2 -0
  166. package/dist/ralplan/__tests__/advisory-activation.test.d.ts.map +1 -0
  167. package/dist/ralplan/__tests__/advisory-activation.test.js +700 -0
  168. package/dist/ralplan/__tests__/advisory-activation.test.js.map +1 -0
  169. package/dist/ralplan/__tests__/advisory-detached-transition.test.d.ts +2 -0
  170. package/dist/ralplan/__tests__/advisory-detached-transition.test.d.ts.map +1 -0
  171. package/dist/ralplan/__tests__/advisory-detached-transition.test.js +88 -0
  172. package/dist/ralplan/__tests__/advisory-detached-transition.test.js.map +1 -0
  173. package/dist/ralplan/__tests__/advisory.test.d.ts +2 -0
  174. package/dist/ralplan/__tests__/advisory.test.d.ts.map +1 -0
  175. package/dist/ralplan/__tests__/advisory.test.js +1087 -0
  176. package/dist/ralplan/__tests__/advisory.test.js.map +1 -0
  177. package/dist/ralplan/__tests__/runtime.test.js +416 -7
  178. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  179. package/dist/ralplan/advisory-activation-verifier.d.ts +19 -0
  180. package/dist/ralplan/advisory-activation-verifier.d.ts.map +1 -0
  181. package/dist/ralplan/advisory-activation-verifier.js +77 -0
  182. package/dist/ralplan/advisory-activation-verifier.js.map +1 -0
  183. package/dist/ralplan/advisory-activation.d.ts +34 -0
  184. package/dist/ralplan/advisory-activation.d.ts.map +1 -0
  185. package/dist/ralplan/advisory-activation.js +205 -0
  186. package/dist/ralplan/advisory-activation.js.map +1 -0
  187. package/dist/ralplan/advisory-contract.d.ts +103 -0
  188. package/dist/ralplan/advisory-contract.d.ts.map +1 -0
  189. package/dist/ralplan/advisory-contract.js +83 -0
  190. package/dist/ralplan/advisory-contract.js.map +1 -0
  191. package/dist/ralplan/advisory-detached-transition.d.ts +11 -0
  192. package/dist/ralplan/advisory-detached-transition.d.ts.map +1 -0
  193. package/dist/ralplan/advisory-detached-transition.js +21 -0
  194. package/dist/ralplan/advisory-detached-transition.js.map +1 -0
  195. package/dist/ralplan/advisory-evidence.d.ts +91 -0
  196. package/dist/ralplan/advisory-evidence.d.ts.map +1 -0
  197. package/dist/ralplan/advisory-evidence.js +393 -0
  198. package/dist/ralplan/advisory-evidence.js.map +1 -0
  199. package/dist/ralplan/advisory-lifecycle-validation.d.ts +11 -0
  200. package/dist/ralplan/advisory-lifecycle-validation.d.ts.map +1 -0
  201. package/dist/ralplan/advisory-lifecycle-validation.js +72 -0
  202. package/dist/ralplan/advisory-lifecycle-validation.js.map +1 -0
  203. package/dist/ralplan/advisory-postconditions.d.ts +3 -0
  204. package/dist/ralplan/advisory-postconditions.d.ts.map +1 -0
  205. package/dist/ralplan/advisory-postconditions.js +33 -0
  206. package/dist/ralplan/advisory-postconditions.js.map +1 -0
  207. package/dist/ralplan/advisory-recovery-journal.d.ts +56 -0
  208. package/dist/ralplan/advisory-recovery-journal.d.ts.map +1 -0
  209. package/dist/ralplan/advisory-recovery-journal.js +136 -0
  210. package/dist/ralplan/advisory-recovery-journal.js.map +1 -0
  211. package/dist/ralplan/advisory-storage.d.ts +24 -0
  212. package/dist/ralplan/advisory-storage.d.ts.map +1 -0
  213. package/dist/ralplan/advisory-storage.js +106 -0
  214. package/dist/ralplan/advisory-storage.js.map +1 -0
  215. package/dist/ralplan/advisory.d.ts +99 -0
  216. package/dist/ralplan/advisory.d.ts.map +1 -0
  217. package/dist/ralplan/advisory.js +914 -0
  218. package/dist/ralplan/advisory.js.map +1 -0
  219. package/dist/ralplan/documented-leader-preflight.d.ts +8 -0
  220. package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
  221. package/dist/ralplan/documented-leader-preflight.js +60 -2
  222. package/dist/ralplan/documented-leader-preflight.js.map +1 -1
  223. package/dist/ralplan/runtime-advisory-lifecycle.d.ts +74 -0
  224. package/dist/ralplan/runtime-advisory-lifecycle.d.ts.map +1 -0
  225. package/dist/ralplan/runtime-advisory-lifecycle.js +352 -0
  226. package/dist/ralplan/runtime-advisory-lifecycle.js.map +1 -0
  227. package/dist/ralplan/runtime-contract.d.ts +126 -0
  228. package/dist/ralplan/runtime-contract.d.ts.map +1 -0
  229. package/dist/ralplan/runtime-contract.js +2 -0
  230. package/dist/ralplan/runtime-contract.js.map +1 -0
  231. package/dist/ralplan/runtime.d.ts +6 -109
  232. package/dist/ralplan/runtime.d.ts.map +1 -1
  233. package/dist/ralplan/runtime.js +174 -56
  234. package/dist/ralplan/runtime.js.map +1 -1
  235. package/dist/scripts/__tests__/postinstall.test.js +26 -0
  236. package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
  237. package/dist/scripts/__tests__/ralplan-advisory-hook.test.d.ts +2 -0
  238. package/dist/scripts/__tests__/ralplan-advisory-hook.test.d.ts.map +1 -0
  239. package/dist/scripts/__tests__/ralplan-advisory-hook.test.js +299 -0
  240. package/dist/scripts/__tests__/ralplan-advisory-hook.test.js.map +1 -0
  241. package/dist/scripts/__tests__/smoke-packed-install.test.js +102 -8
  242. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  243. package/dist/scripts/codex-native-hook.d.ts +20 -0
  244. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  245. package/dist/scripts/codex-native-hook.js +226 -15
  246. package/dist/scripts/codex-native-hook.js.map +1 -1
  247. package/dist/scripts/postinstall.d.ts +7 -0
  248. package/dist/scripts/postinstall.d.ts.map +1 -1
  249. package/dist/scripts/postinstall.js +40 -0
  250. package/dist/scripts/postinstall.js.map +1 -1
  251. package/dist/scripts/smoke-packed-install.d.ts +21 -5
  252. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  253. package/dist/scripts/smoke-packed-install.js +157 -57
  254. package/dist/scripts/smoke-packed-install.js.map +1 -1
  255. package/dist/state/__tests__/mode-binding-lease.test.d.ts +2 -0
  256. package/dist/state/__tests__/mode-binding-lease.test.d.ts.map +1 -0
  257. package/dist/state/__tests__/mode-binding-lease.test.js +498 -0
  258. package/dist/state/__tests__/mode-binding-lease.test.js.map +1 -0
  259. package/dist/state/__tests__/operations.test.js +1 -0
  260. package/dist/state/__tests__/operations.test.js.map +1 -1
  261. package/dist/state/__tests__/pinned-atomic-file.test.d.ts +2 -0
  262. package/dist/state/__tests__/pinned-atomic-file.test.d.ts.map +1 -0
  263. package/dist/state/__tests__/pinned-atomic-file.test.js +438 -0
  264. package/dist/state/__tests__/pinned-atomic-file.test.js.map +1 -0
  265. package/dist/state/__tests__/skill-active-exact-session-transaction.test.d.ts +2 -0
  266. package/dist/state/__tests__/skill-active-exact-session-transaction.test.d.ts.map +1 -0
  267. package/dist/state/__tests__/skill-active-exact-session-transaction.test.js +179 -0
  268. package/dist/state/__tests__/skill-active-exact-session-transaction.test.js.map +1 -0
  269. package/dist/state/__tests__/skill-active.test.js +29 -1
  270. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  271. package/dist/state/mode-binding-lease-helper.d.ts +2 -0
  272. package/dist/state/mode-binding-lease-helper.d.ts.map +1 -0
  273. package/dist/state/mode-binding-lease-helper.js +623 -0
  274. package/dist/state/mode-binding-lease-helper.js.map +1 -0
  275. package/dist/state/mode-binding-lease.d.ts +25 -0
  276. package/dist/state/mode-binding-lease.d.ts.map +1 -0
  277. package/dist/state/mode-binding-lease.js +380 -0
  278. package/dist/state/mode-binding-lease.js.map +1 -0
  279. package/dist/state/operations.d.ts +29 -1
  280. package/dist/state/operations.d.ts.map +1 -1
  281. package/dist/state/operations.js +203 -122
  282. package/dist/state/operations.js.map +1 -1
  283. package/dist/state/pinned-atomic-file-darwin-client.d.ts +34 -0
  284. package/dist/state/pinned-atomic-file-darwin-client.d.ts.map +1 -0
  285. package/dist/state/pinned-atomic-file-darwin-client.js +174 -0
  286. package/dist/state/pinned-atomic-file-darwin-client.js.map +1 -0
  287. package/dist/state/pinned-atomic-file-darwin-helper.d.ts +2 -0
  288. package/dist/state/pinned-atomic-file-darwin-helper.d.ts.map +1 -0
  289. package/dist/state/pinned-atomic-file-darwin-helper.js +275 -0
  290. package/dist/state/pinned-atomic-file-darwin-helper.js.map +1 -0
  291. package/dist/state/pinned-atomic-file-darwin-janitor.d.ts +2 -0
  292. package/dist/state/pinned-atomic-file-darwin-janitor.d.ts.map +1 -0
  293. package/dist/state/pinned-atomic-file-darwin-janitor.js +272 -0
  294. package/dist/state/pinned-atomic-file-darwin-janitor.js.map +1 -0
  295. package/dist/state/pinned-atomic-file.d.ts +29 -0
  296. package/dist/state/pinned-atomic-file.d.ts.map +1 -0
  297. package/dist/state/pinned-atomic-file.js +536 -0
  298. package/dist/state/pinned-atomic-file.js.map +1 -0
  299. package/dist/state/process-identity.d.ts +30 -0
  300. package/dist/state/process-identity.d.ts.map +1 -0
  301. package/dist/state/process-identity.js +99 -0
  302. package/dist/state/process-identity.js.map +1 -0
  303. package/dist/state/skill-active.d.ts +18 -1
  304. package/dist/state/skill-active.d.ts.map +1 -1
  305. package/dist/state/skill-active.js +82 -5
  306. package/dist/state/skill-active.js.map +1 -1
  307. package/dist/state/workflow-transition-reconcile.js +1 -1
  308. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  309. package/dist/team/__tests__/tmux-session.test.js +109 -0
  310. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  311. package/dist/team/tmux-session.d.ts.map +1 -1
  312. package/dist/team/tmux-session.js +10 -1
  313. package/dist/team/tmux-session.js.map +1 -1
  314. package/dist/utils/__tests__/file-durability.test.js +20 -0
  315. package/dist/utils/__tests__/file-durability.test.js.map +1 -1
  316. package/dist/utils/file-durability.d.ts +1 -1
  317. package/dist/utils/file-durability.d.ts.map +1 -1
  318. package/dist/utils/file-durability.js.map +1 -1
  319. package/dist/verification/__tests__/ci-rust-gates.test.js +12 -4
  320. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  321. package/dist/verification/__tests__/ci-trusted-publish.test.d.ts +2 -0
  322. package/dist/verification/__tests__/ci-trusted-publish.test.d.ts.map +1 -0
  323. package/dist/verification/__tests__/ci-trusted-publish.test.js +205 -0
  324. package/dist/verification/__tests__/ci-trusted-publish.test.js.map +1 -0
  325. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +10 -5
  326. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
  327. package/dist/verification/__tests__/publish-npm-manual-retired.test.d.ts +2 -0
  328. package/dist/verification/__tests__/publish-npm-manual-retired.test.d.ts.map +1 -0
  329. package/dist/verification/__tests__/publish-npm-manual-retired.test.js +22 -0
  330. package/dist/verification/__tests__/publish-npm-manual-retired.test.js.map +1 -0
  331. package/package.json +1 -1
  332. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  333. package/plugins/oh-my-codex/skills/doctor/SKILL.md +1 -1
  334. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +1 -1
  335. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +10 -1
  336. package/plugins/oh-my-codex/skills/team/SKILL.md +2 -0
  337. package/skills/doctor/SKILL.md +1 -1
  338. package/skills/omx-setup/SKILL.md +1 -1
  339. package/skills/ralplan/SKILL.md +10 -1
  340. package/skills/team/SKILL.md +2 -0
  341. package/src/scripts/__tests__/postinstall.test.ts +28 -0
  342. package/src/scripts/__tests__/ralplan-advisory-hook.test.ts +320 -0
  343. package/src/scripts/__tests__/smoke-packed-install.test.ts +120 -7
  344. package/src/scripts/codex-native-hook.ts +220 -10
  345. package/src/scripts/postinstall.ts +46 -0
  346. package/src/scripts/smoke-packed-install.ts +175 -70
@@ -53,6 +53,8 @@ import {
53
53
  assertCodexBatchWriteResult,
54
54
  assertGeneratedTrustMatchesCodex,
55
55
  managedCodexHooksByEvent,
56
+ assertNativeHookAdvisoryPreToolUse,
57
+ listPersistedStateFiles,
56
58
  } from '../smoke-packed-install.js';
57
59
  import { parseNativeSubagentResultDisposition } from '../../leader/contract.js';
58
60
 
@@ -1106,7 +1108,7 @@ test('packed install smoke covers directive activation and terminal false-activa
1106
1108
  { name: 'compact-explicit-negation', prompt: '$ralplan,$autopilot are prohibited', expectedSkill: null, expectedStopBlock: false },
1107
1109
  { name: 'compact-implicit-negation', prompt: 'Autopilot mode،deep interview are prohibited.', expectedSkill: null, expectedStopBlock: false },
1108
1110
  { name: 'doc-clause-local-prefix', prompt: '$ralplan; $autopilot is documented in the guide.', expectedSkill: 'ralplan', expectedStopBlock: true },
1109
- { name: 'doc-chain-described', prompt: 'use $ralplan is the workflow command; autopilot mode is documented in the guide; $team execute it', expectedSkill: 'team', expectedStopBlock: false, insideTmux: true },
1111
+ { name: 'doc-chain-described', prompt: 'use $ralplan is the workflow command; autopilot mode is documented in the guide; $team execute it', expectedSkill: 'team', expectedStopBlock: true, insideTmux: true },
1110
1112
  { name: 'doc-chain-workflow', prompt: 'use $ralplan is the workflow command; autopilot mode is workflow documentation; use $ralph execute it', expectedSkill: 'ralph', expectedStopBlock: true },
1111
1113
  { name: 'ref-inline-explicit', prompt: '[docs]: $ralplan\n$autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
1112
1114
  { name: 'ref-inline-prompts', prompt: '[docs]: /prompts:architect\n$autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
@@ -1132,10 +1134,10 @@ test('packed install smoke covers directive activation and terminal false-activa
1132
1134
  { name: 'neg-fw-dot-reopen', prompt: 'Do not run $ralplan. use $autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
1133
1135
  { name: 'neg-greek-q-reopen', prompt: 'Do not run $ralplan; use $autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
1134
1136
  { name: 'unicode-attached-contrast', prompt: 'Do not use deep interview яbut use autopilot mode.', expectedSkill: null, expectedStopBlock: false },
1135
- { name: 'prefix-list-followup', prompt: 'Do not run $ralplan, $autopilot; use $team execute it', expectedSkill: 'team', expectedStopBlock: false, insideTmux: true },
1137
+ { name: 'prefix-list-followup', prompt: 'Do not run $ralplan, $autopilot; use $team execute it', expectedSkill: 'team', expectedStopBlock: true, insideTmux: true },
1136
1138
  { name: 'mixed-postposed-chain', prompt: '$ralplan, autopilot mode, $team are prohibited.', expectedSkill: null, expectedStopBlock: false },
1137
- { name: 'implicit-first-doc-chain', prompt: 'Autopilot mode and $ralplan are workflow commands; use $team execute it', expectedSkill: 'team', expectedStopBlock: false, insideTmux: true },
1138
- { name: 'both-mixed-doc-followup', prompt: 'Both autopilot mode and $ralplan are workflow commands; use $team execute it', expectedSkill: 'team', expectedStopBlock: false, insideTmux: true },
1139
+ { name: 'implicit-first-doc-chain', prompt: 'Autopilot mode and $ralplan are workflow commands; use $team execute it', expectedSkill: 'team', expectedStopBlock: true, insideTmux: true },
1140
+ { name: 'both-mixed-doc-followup', prompt: 'Both autopilot mode and $ralplan are workflow commands; use $team execute it', expectedSkill: 'team', expectedStopBlock: true, insideTmux: true },
1139
1141
  { name: 'doc-semicolon-preserves-earlier', prompt: 'Use autopilot mode; use $ralplan is the workflow command.', expectedSkill: 'autopilot', expectedStopBlock: true },
1140
1142
  { name: 'doc-independent-comma', prompt: 'Use autopilot mode, and $ralplan is documented in the guide.', expectedSkill: 'autopilot', expectedStopBlock: true },
1141
1143
  { name: 'reference-unclosed-quote-destination', prompt: '[docs]: "target\n$autopilot build it', expectedSkill: null, expectedStopBlock: false },
@@ -1183,14 +1185,14 @@ test('packed install smoke covers directive activation and terminal false-activa
1183
1185
  { name: 'percent-suffix', prompt: '$ralplan%docs', expectedSkill: null, expectedStopBlock: false },
1184
1186
  { name: 'fullwidth-percent-suffix', prompt: '$ralplan%docs', expectedSkill: null, expectedStopBlock: false },
1185
1187
  { name: 'g1a-ordered-multi-skill', prompt: '$ralplan, $autopilot; $team', expectedSkill: 'ralplan', expectedStopBlock: true, expectedDeferredSkills: ['autopilot', 'team'], expectedActiveSkills: ['ralplan'], insideTmux: true },
1186
- { name: 'g1c-duplicate-alias', prompt: '$autopilot $oh-my-codex:autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true, expectedDeferredSkills: [], expectedActiveSkills: [] },
1188
+ { name: 'g1c-duplicate-alias', prompt: '$autopilot $oh-my-codex:autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true, expectedDeferredSkills: [], expectedActiveSkills: ['autopilot'] },
1187
1189
  { name: 'b3-longer-valid-fence', prompt: '```text\n$autopilot build it\n````\n$ralplan plan it', expectedSkill: 'ralplan', expectedStopBlock: true },
1188
1190
  { name: 'b4-shorter-invalid-fence', prompt: '````text\n$autopilot build it\n```\n$ralplan plan it', expectedSkill: null, expectedStopBlock: false },
1189
1191
  { name: 'b5-different-marker-invalid-fence', prompt: '```text\n$autopilot build it\n~~~\n$ralplan plan it', expectedSkill: null, expectedStopBlock: false },
1190
1192
  ]);
1191
1193
  });
1192
1194
 
1193
- test('packed regression workflow expectations require active Autopilot and Ralplan activation', () => {
1195
+ test('packed regression workflow expectations require active supported skills and failed retired ralph receipts', () => {
1194
1196
  assert.doesNotThrow(() => assertPackedRegressionWorkflowState(
1195
1197
  { name: 'active-ralplan', expectedSkill: 'ralplan' },
1196
1198
  { active: true, skill: 'ralplan' },
@@ -1203,11 +1205,26 @@ test('packed regression workflow expectations require active Autopilot and Ralpl
1203
1205
  { name: 'failed-autopilot', expectedSkill: 'autopilot' },
1204
1206
  { active: false, skill: 'autopilot', phase: 'failed', active_skills: [] },
1205
1207
  ), /persisted unexpected workflow state/);
1208
+ assert.doesNotThrow(() => assertPackedRegressionWorkflowState(
1209
+ { name: 'retired-ralph', expectedSkill: 'ralph' },
1210
+ {
1211
+ active: false,
1212
+ skill: 'ralph',
1213
+ phase: 'failed',
1214
+ transition_error: 'Skill "$ralph" has been removed. Use "$ultragoal" instead. The `omx ralph` CLI and ralph persistence runtime are unaffected.',
1215
+ active_skills: [],
1216
+ },
1217
+ ));
1218
+ assert.throws(() => assertPackedRegressionWorkflowState(
1219
+ { name: 'active-retired-ralph', expectedSkill: 'ralph' },
1220
+ { active: true, skill: 'ralph', phase: 'executing' },
1221
+ ), /unexpected retired ralph state/);
1206
1222
  });
1207
1223
 
1208
- test('packed regression Stop expectations keep active Autopilot continuation enabled', () => {
1224
+ test('packed regression Stop expectations keep active workflows blocked but retired ralph terminal', () => {
1209
1225
  assert.equal(shouldPackedRegressionStopBlock({ expectedSkill: 'ralplan', expectedStopBlock: true }), true);
1210
1226
  assert.equal(shouldPackedRegressionStopBlock({ expectedSkill: 'autopilot', expectedStopBlock: true }), true);
1227
+ assert.equal(shouldPackedRegressionStopBlock({ expectedSkill: 'ralph', expectedStopBlock: true }), false);
1211
1228
  });
1212
1229
 
1213
1230
  test('packed regression environment clears inherited Team routing state', () => {
@@ -1695,3 +1712,99 @@ test('ensureRepoDependencies falls back to npm ci when no reusable node_modules
1695
1712
  await rm(root, { recursive: true, force: true });
1696
1713
  }
1697
1714
  });
1715
+ test('assertNativeHookAdvisoryPreToolUse accepts the two documented advisory shapes', () => {
1716
+ // Empty no-op: the hook intentionally produced no advisory content (#3497).
1717
+ assertNativeHookAdvisoryPreToolUse('advisory-empty', {});
1718
+
1719
+ // Documented advisory context with the PreToolUse event name.
1720
+ assertNativeHookAdvisoryPreToolUse('advisory-context', {
1721
+ systemMessage: 'advisory guidance',
1722
+ hookSpecificOutput: {
1723
+ hookEventName: 'PreToolUse',
1724
+ additionalContext: 'advisory guidance',
1725
+ },
1726
+ });
1727
+
1728
+ // systemMessage alone, without a hookSpecificOutput envelope, is also advisory.
1729
+ assertNativeHookAdvisoryPreToolUse('advisory-system-message', { systemMessage: 'guidance only' });
1730
+ });
1731
+
1732
+ test('assertNativeHookAdvisoryPreToolUse rejects outputs that would hide a regression', () => {
1733
+ const rejections: Array<[string, Record<string, unknown>, RegExp]> = [
1734
+ ['hard block', { decision: 'block', reason: 'nope' }, /hard block/],
1735
+ ['stopped continuation', { continue: false }, /stopped continuation/],
1736
+ ['stopReason', { stopReason: 'native_hook_stdin_parse_error' }, /emitted stopReason/],
1737
+ ['permission deny', {
1738
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny' },
1739
+ }, /permissionDecision "deny"/],
1740
+ ['permission allow', {
1741
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow' },
1742
+ }, /permissionDecision "allow"/],
1743
+ ['wrong event name', {
1744
+ systemMessage: 'x',
1745
+ hookSpecificOutput: { hookEventName: 'Stop', additionalContext: 'x' },
1746
+ }, /hookSpecificOutput names "Stop"/],
1747
+ ['non-string system message', { systemMessage: 1 }, /malformed systemMessage/],
1748
+ ['empty system message', { systemMessage: '' }, /malformed systemMessage/],
1749
+ ['empty envelope', { hookSpecificOutput: {} }, /malformed PreToolUse advisory envelope/],
1750
+ ['system message plus empty envelope', {
1751
+ systemMessage: 'x',
1752
+ hookSpecificOutput: {},
1753
+ }, /malformed PreToolUse advisory envelope/],
1754
+ ['envelope without event name', {
1755
+ systemMessage: 'x',
1756
+ hookSpecificOutput: { additionalContext: 'x' },
1757
+ }, /malformed PreToolUse advisory envelope/],
1758
+ ['envelope without context', {
1759
+ systemMessage: 'x',
1760
+ hookSpecificOutput: { hookEventName: 'PreToolUse' },
1761
+ }, /malformed PreToolUse advisory envelope/],
1762
+ ['mismatched envelope content', {
1763
+ systemMessage: 'x',
1764
+ hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: 'y' },
1765
+ }, /does not mirror systemMessage/],
1766
+ ['unexpected top-level field', { systemMessage: 'x', reason: 'stray' }, /unexpected top-level field "reason"/],
1767
+ ['unexpected hook field', {
1768
+ systemMessage: 'x',
1769
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecisionReason: 'stray' },
1770
+ }, /emitted unexpected field "permissionDecisionReason"/],
1771
+ ['malformed hookSpecificOutput', { hookSpecificOutput: 'nope' }, /malformed hookSpecificOutput/],
1772
+ ['array hookSpecificOutput', { hookSpecificOutput: [] }, /malformed hookSpecificOutput/],
1773
+ ];
1774
+ for (const [label, output, pattern] of rejections) {
1775
+ assert.throws(
1776
+ () => assertNativeHookAdvisoryPreToolUse(`probe-${label}`, output),
1777
+ pattern,
1778
+ `${label} must be rejected`,
1779
+ );
1780
+ }
1781
+ });
1782
+
1783
+ test('listPersistedStateFiles permits empty state directory bootstrap but detects persisted artifacts', async () => {
1784
+ const root = await mkdtemp(join(tmpdir(), 'omx-packed-state-artifacts-'));
1785
+ try {
1786
+ const stateRoot = join(root, '.omx', 'state');
1787
+ await mkdir(join(stateRoot, 'sessions', 'nested'), { recursive: true });
1788
+ assert.deepEqual(listPersistedStateFiles(stateRoot), []);
1789
+
1790
+ const persistedFile = join(stateRoot, 'sessions', 'nested', 'skill-active-state.json');
1791
+ await writeFile(persistedFile, '{}\n');
1792
+ assert.deepEqual(listPersistedStateFiles(stateRoot), [persistedFile]);
1793
+ await rm(persistedFile);
1794
+
1795
+ const symlinkPath = join(stateRoot, 'sessions', 'state-link');
1796
+ await symlink(join(root, 'missing-target'), symlinkPath);
1797
+ assert.deepEqual(listPersistedStateFiles(stateRoot), [symlinkPath]);
1798
+ await rm(symlinkPath);
1799
+
1800
+ const rootLink = join(root, 'state-link');
1801
+ await symlink(stateRoot, rootLink);
1802
+ assert.deepEqual(listPersistedStateFiles(rootLink), [rootLink]);
1803
+
1804
+ const rootFile = join(root, 'state-file');
1805
+ await writeFile(rootFile, '{}\n');
1806
+ assert.deepEqual(listPersistedStateFiles(rootFile), [rootFile]);
1807
+ } finally {
1808
+ await rm(root, { recursive: true, force: true });
1809
+ }
1810
+ });
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from "child_process";
2
2
  import { accessSync, closeSync, constants as fsConstants, existsSync, lstatSync, openSync, readFileSync, readSync, readdirSync, realpathSync, statSync } from "fs";
3
- import { appendFile, lstat, mkdir, open, readFile, readdir, stat, unlink, writeFile } from "fs/promises";
3
+ import { appendFile, lstat, mkdir, open, readFile, readdir, realpath, stat, unlink, writeFile } from "fs/promises";
4
4
  import { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve } from "path";
5
5
  import { createHash } from "crypto";
6
6
 
@@ -32,6 +32,12 @@ import {
32
32
  } from "../subagents/tracker.js";
33
33
 
34
34
  import { readRoleRoutingMarker, writeRoleRoutingMarker } from "../subagents/role-routing-marker.js";
35
+ import {
36
+ readCurrentRalplanAdvisory,
37
+ reconcileRalplanAdvisory,
38
+ observeRalplanAdvisoryPrompt,
39
+ } from "../ralplan/advisory.js";
40
+ import { activateOrResumeRalplanAdvisory } from "../ralplan/advisory-activation.js";
35
41
  import {
36
42
  resolveCanonicalTeamStateRoot,
37
43
  resolveWorkerTeamStateRootPath,
@@ -57,6 +63,7 @@ import {
57
63
  readUsableSessionState,
58
64
  reconcileNativeSessionStart,
59
65
  resolveSessionPointerContext,
66
+ sessionOwnerFileIdentityMatches,
60
67
  type SessionStartOptions,
61
68
  writeNativeSessionOwner,
62
69
  type SessionState
@@ -210,6 +217,9 @@ interface NativeHookDispatchOptions {
210
217
  /** @internal Scoped deterministic SessionStart durability seam for native-hook tests. */
211
218
  sessionStartOptions?: Pick<SessionStartOptions, 'platform' | 'regularFileSync'>;
212
219
  reconcileHudForPromptSubmitFn?: typeof reconcileHudForPromptSubmit;
220
+ /** @internal Deterministic Advisory reconciliation failure seam for hook tests. */
221
+ reconcileRalplanAdvisoryFn?: typeof reconcileRalplanAdvisory;
222
+ /** @internal Deterministic Advisory detect/read race seam for native-hook tests. */
213
223
  }
214
224
 
215
225
  export interface NativeHookDispatchResult {
@@ -3735,7 +3745,11 @@ function hookCancelIdentity(stats: { dev: number; ino: number; mode: number; uid
3735
3745
  return { dev: stats.dev, ino: stats.ino, mode: stats.mode, uid: stats.uid, size: stats.size, mtimeMs: stats.mtimeMs };
3736
3746
  }
3737
3747
  function hookCancelIdentityMatches(left: HookCancelTargetIdentity, right: HookCancelTargetIdentity): boolean {
3738
- return left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.uid === right.uid && left.size === right.size && left.mtimeMs === right.mtimeMs;
3748
+ return sessionOwnerFileIdentityMatches(left, right, hookCancelPlatform())
3749
+ && left.mode === right.mode
3750
+ && left.uid === right.uid
3751
+ && left.size === right.size
3752
+ && left.mtimeMs === right.mtimeMs;
3739
3753
  }
3740
3754
  function hookCancelTargetMatches(left: HookCancelTargetIdentity, right: HookCancelTargetIdentity): boolean {
3741
3755
  return left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.uid === right.uid;
@@ -5552,6 +5566,7 @@ const NATIVE_CODEX_GOAL_READ_TOOL_NAMES = new Set([
5552
5566
  "get_goal",
5553
5567
  "functions.get_goal",
5554
5568
  "functionsget_goal",
5569
+ "mcp__omx_goal__get_goal",
5555
5570
  ]);
5556
5571
  const NATIVE_CODEX_GOAL_LIFECYCLE_TOOL_NAMES = new Set([
5557
5572
  "create_goal",
@@ -5560,6 +5575,8 @@ const NATIVE_CODEX_GOAL_LIFECYCLE_TOOL_NAMES = new Set([
5560
5575
  "functions.update_goal",
5561
5576
  "functionscreate_goal",
5562
5577
  "functionsupdate_goal",
5578
+ "mcp__omx_goal__create_goal",
5579
+ "mcp__omx_goal__update_goal",
5563
5580
  ]);
5564
5581
 
5565
5582
  function canonicalizeNativeCodexGoalToolName(name: string): string {
@@ -10133,6 +10150,111 @@ function directOmxCancelCommandHasTrustedExecutionContext(command: string, cwd:
10133
10150
  return omxOrGjcExecutionContextIsTrusted(command, cwd, ["omx"]);
10134
10151
  }
10135
10152
 
10153
+ export type RalplanAdvisoryStateDetection =
10154
+ | { status: "normal"; root: string }
10155
+ | { status: "missing"; root: string; reason: "advisory_binding_without_state_root" }
10156
+ | { status: "unreadable"; root: string; reason: string }
10157
+ | { status: "none"; root: string };
10158
+
10159
+ async function sessionHasAdvisoryBinding(cwd: string, sessionId: string): Promise<boolean> {
10160
+ const path = join(getBaseStateDir(cwd), "sessions", sessionId, "ralplan-state.json");
10161
+ let handle: Awaited<ReturnType<typeof open>>;
10162
+ try {
10163
+ handle = await open(path, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
10164
+ } catch (error) {
10165
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
10166
+ throw error;
10167
+ }
10168
+ try {
10169
+ const info = await handle.stat();
10170
+ if (!info.isFile() || info.nlink !== 1 || info.size > 1024 * 1024) throw new Error("ralplan_advisory_binding_file_invalid");
10171
+ const value = JSON.parse((await handle.readFile()).toString("utf8")) as unknown;
10172
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("ralplan_advisory_binding_json_invalid");
10173
+ return (value as Record<string, unknown>).workflow_variant === "advisory";
10174
+ } finally {
10175
+ await handle.close();
10176
+ }
10177
+ }
10178
+
10179
+ export async function detectRalplanAdvisoryState(cwd: string, sessionId: string): Promise<RalplanAdvisoryStateDetection> {
10180
+ let canonicalCwd: string;
10181
+ try { canonicalCwd = await realpath(cwd); }
10182
+ catch (error) {
10183
+ const root = join(getBaseStateDir(cwd), "sessions", sessionId, "ralplan-advisory");
10184
+ return { status: "unreadable", root, reason: `cwd_realpath_${(error as NodeJS.ErrnoException).code ?? "failed"}` };
10185
+ }
10186
+ const root = join(getBaseStateDir(canonicalCwd), "sessions", sessionId, "ralplan-advisory");
10187
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(sessionId)) {
10188
+ return { status: "unreadable", root, reason: "session_id_invalid" };
10189
+ }
10190
+ try {
10191
+ const info = await lstat(root);
10192
+ let canonical: string;
10193
+ try { canonical = await realpath(root); }
10194
+ catch (error) { return { status: "unreadable", root, reason: `state_root_realpath_${(error as NodeJS.ErrnoException).code ?? "failed"}` }; }
10195
+ if (!info.isDirectory()) return { status: "unreadable", root, reason: "state_root_not_canonical_directory" };
10196
+ if (canonical !== root) return { status: "unreadable", root, reason: "state_root_not_canonical" };
10197
+ return { status: "normal", root };
10198
+ } catch (error) {
10199
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
10200
+ return { status: "unreadable", root, reason: `state_root_lstat_${(error as NodeJS.ErrnoException).code ?? "failed"}` };
10201
+ }
10202
+ }
10203
+ try {
10204
+ return await sessionHasAdvisoryBinding(canonicalCwd, sessionId)
10205
+ ? { status: "missing", root, reason: "advisory_binding_without_state_root" }
10206
+ : { status: "none", root };
10207
+ } catch (error) {
10208
+ return { status: "unreadable", root, reason: `binding_${(error as NodeJS.ErrnoException).code ?? "invalid"}` };
10209
+ }
10210
+ }
10211
+
10212
+ export function buildRalplanAdvisoryRoutingObservation(
10213
+ intent: string,
10214
+ projection: Awaited<ReturnType<typeof readCurrentRalplanAdvisory>>,
10215
+ binding: Record<string, unknown> | null,
10216
+ ): string | null {
10217
+ if (intent !== "execute" || !projection) return null;
10218
+ if (projection.corruption) {
10219
+ return `Ralplan Advisory evidence is not a valid lifecycle projection (${projection.corruption}); this non-authoritative diagnostic does not grant or deny host tool permission.`;
10220
+ }
10221
+ const fence = projection.fence;
10222
+ if (!fence) return "Ralplan Advisory planning has not reached a terminal lifecycle state; no automatic execution handoff was created.";
10223
+ const matchingAdvisoryBinding = binding?.workflow_variant === "advisory"
10224
+ && binding.advisory_generation_id === projection.activation.generation_id;
10225
+ const conflictingWorkflow = binding?.active === true && !matchingAdvisoryBinding;
10226
+ if (conflictingWorkflow) return null;
10227
+ if (fence.state === "pending_closeout") {
10228
+ return "Ralplan Advisory closeout is still pending; no automatic execution handoff was created.";
10229
+ }
10230
+ if (fence.state === "recovery_required") {
10231
+ return "Ralplan Advisory evidence requires lifecycle recovery; no automatic execution handoff was created.";
10232
+ }
10233
+ if (fence.state === "abandoned") {
10234
+ return `Ralplan Advisory ended as ${fence.outcome ?? "abandoned"}, not as an approved planning result; later instructions follow normal host rules.`;
10235
+ }
10236
+ const lifecycle = projection.journal?.terminal_mode_updates?.ralplan_review_lifecycle;
10237
+ const lifecycleRecord = lifecycle && typeof lifecycle === "object" && !Array.isArray(lifecycle)
10238
+ ? lifecycle as Record<string, unknown>
10239
+ : null;
10240
+ const complete = fence.state === "closed" && fence.outcome === "approved" && fence.integrity_status === "proven"
10241
+ && projection.journal?.phase === "committed" && projection.journal.outcome === "approved"
10242
+ && lifecycleRecord?.complete === true
10243
+ && lifecycleRecord.sequence_valid === true
10244
+ && lifecycleRecord.iteration === fence.iteration
10245
+ && lifecycleRecord.iteration_id === fence.iteration_id
10246
+ && lifecycleRecord.plan_manifest_sha256 === fence.plan_manifest_sha256
10247
+ && lifecycleRecord.architect_review_sha256 === fence.architect_review_sha256
10248
+ && lifecycleRecord.critic_review_sha256 === fence.critic_review_sha256
10249
+ && lifecycleRecord.evidence_bundle_sha256 === fence.evidence_bundle_sha256
10250
+ && lifecycleRecord.evidence_scope === "local_runtime"
10251
+ && lifecycleRecord.host_observable === false
10252
+ && lifecycleRecord.host_verified === false;
10253
+ return complete
10254
+ ? "Ralplan Advisory planning is complete and its byte-bound evidence remains auditable. This execution request is a non-authoritative routing observation only; no local Advisory file or classifier grants tool permission or an automatic execution handoff."
10255
+ : "Ralplan Advisory does not contain a complete approved and proven planning lifecycle; no automatic execution handoff was created.";
10256
+ }
10257
+
10136
10258
  function isCommandResolutionSensitiveEnvironmentName(name: string): boolean {
10137
10259
  // Variables that redirect where the shell resolves the executable itself.
10138
10260
  // A leading PATH/PATHEXT override can point a bare `omx`/`rtk` at an
@@ -21769,6 +21891,7 @@ export async function dispatchCodexNativeHook(
21769
21891
  ): Promise<NativeHookDispatchResult> {
21770
21892
  const hookEventName = readHookEventName(payload);
21771
21893
  const cwd = options.cwd ?? (safeString(payload.cwd).trim() || process.cwd());
21894
+ const reconcileAdvisory = options.reconcileRalplanAdvisoryFn ?? reconcileRalplanAdvisory;
21772
21895
  const omxEventName = mapCodexHookEventToOmxEvent(hookEventName);
21773
21896
  // #3497 / C1 boundary: documented-leader PreToolUse hard gate removed.
21774
21897
  if (hookEventName === "PreToolUse" && safeString(payload.tool_name).trim() === "Bash") {
@@ -21820,6 +21943,7 @@ export async function dispatchCodexNativeHook(
21820
21943
  let goalWorkflowAdditionalContext: string | null = null;
21821
21944
  let ultragoalSteeringAdditionalContext: string | null = null;
21822
21945
  let teamNoticeAdditionalContext: string | null = null;
21946
+ let advisoryAdditionalContext: string | null = null;
21823
21947
  let teamNoticeTargetKey: string | null = null;
21824
21948
  let promptClassification: KeywordInputClassification | null = null;
21825
21949
 
@@ -22183,13 +22307,84 @@ export async function dispatchCodexNativeHook(
22183
22307
  (isSubagentSessionStart || isSubagentStop)
22184
22308
  && shouldSuppressSubagentLifecycleHookDispatch();
22185
22309
 
22310
+ const advisoryStateDetection = canonicalSessionId
22311
+ && (hookEventName === "SessionStart" || hookEventName === "Stop" || hookEventName === "UserPromptSubmit")
22312
+ ? await detectRalplanAdvisoryState(policyCwd, canonicalSessionId)
22313
+ : null;
22314
+ if ((hookEventName === "SessionStart" || hookEventName === "Stop") && canonicalSessionId
22315
+ && advisoryStateDetection?.status === "normal") {
22316
+ try {
22317
+ const reconciledAdvisory = await reconcileAdvisory(policyCwd, canonicalSessionId);
22318
+ if (reconciledAdvisory?.corruption === "live_session_binding_conflict"
22319
+ || reconciledAdvisory?.corruption === "live_session_binding_unreadable") {
22320
+ throw new Error(reconciledAdvisory.corruption);
22321
+ }
22322
+ } catch (error) {
22323
+ const diagnostic = `Ralplan Advisory lifecycle reconciliation reported a non-authoritative diagnostic: ${error instanceof Error ? error.message : String(error)}. It does not grant or deny host tool permission.`;
22324
+ if (hookEventName === "SessionStart") {
22325
+ advisoryAdditionalContext = diagnostic;
22326
+ } else {
22327
+ await appendToLog(cwd, {
22328
+ event: "ralplan_advisory_reconciliation_diagnostic",
22329
+ hook_event_name: "Stop",
22330
+ session_id: canonicalSessionId,
22331
+ reason: error instanceof Error ? error.message : String(error),
22332
+ non_authoritative: true,
22333
+ timestamp: new Date().toISOString(),
22334
+ }).catch(() => {});
22335
+ }
22336
+ }
22337
+ }
22338
+
22186
22339
  if (hookEventName === "UserPromptSubmit") {
22187
22340
  const prompt = readPromptText(payload);
22188
- if (!isSubagentPromptSubmit) {
22189
- teamNoticeTargetKey = parseTeamNoticeLedgerPrompt(prompt);
22341
+ const advisoryThreadKind = promptTurnContext?.status === "authorized"
22342
+ && promptTurnContext.authorization.targetRelation !== "explicit-independent"
22343
+ && promptTurnContext.authorization.thread.kind === "root-or-drift"
22344
+ ? "root-or-drift" : "unknown";
22345
+ if (!isSubagentPromptSubmit) promptClassification = classifyKeywordInput(prompt);
22346
+ if (canonicalSessionId && !isSubagentPromptSubmit && advisoryStateDetection?.status === "normal") {
22347
+ try {
22348
+ await activateOrResumeRalplanAdvisory({
22349
+ cwd: policyCwd, sessionId: canonicalSessionId, rootThreadId: threadId,
22350
+ activationTurnId: turnId, prompt, resumeOnly: true, producer: "native", threadKind: advisoryThreadKind,
22351
+ });
22352
+ const advisory = await observeRalplanAdvisoryPrompt({
22353
+ cwd: policyCwd,
22354
+ sessionId: canonicalSessionId,
22355
+ turnId,
22356
+ threadId,
22357
+ prompt,
22358
+ producer: "native",
22359
+ threadKind: promptTurnContext?.status === "authorized"
22360
+ && promptTurnContext.authorization.targetRelation !== "explicit-independent"
22361
+ ? "root-or-drift" : "unknown",
22362
+ isSubagentPromptSubmit,
22363
+ markedContinuation: payload.continuation === true
22364
+ || payload.is_continuation === true
22365
+ || safeString(payload.source).toLowerCase().includes("continuation"),
22366
+ synthetic: payload.synthetic === true
22367
+ || payload.auto_nudge === true
22368
+ || safeString(payload.source).toLowerCase().includes("nudge"),
22369
+ reservedInput: promptClassification?.reservedInput ?? null,
22370
+ });
22371
+ if ((advisory.intent === "replan" || advisory.intent === "new_advisory")
22372
+ && advisory.projection?.activation) {
22373
+ const activated = await activateOrResumeRalplanAdvisory({
22374
+ cwd: policyCwd, sessionId: canonicalSessionId, rootThreadId: threadId,
22375
+ activationTurnId: turnId, prompt, producer: "native", threadKind: advisoryThreadKind,
22376
+ predecessorGenerationId: advisory.projection.activation.generation_id,
22377
+ });
22378
+ if (activated) advisory.projection = activated.projection;
22379
+ }
22380
+ const advisoryBinding = await readModeStateForSession("ralplan", canonicalSessionId, policyCwd);
22381
+ advisoryAdditionalContext = buildRalplanAdvisoryRoutingObservation(advisory.intent, advisory.projection, advisoryBinding);
22382
+ } catch (error) {
22383
+ advisoryAdditionalContext = `Ralplan Advisory lifecycle reconciliation reported a non-authoritative diagnostic: ${error instanceof Error ? error.message : String(error)}. It does not grant or deny host tool permission.`;
22384
+ }
22190
22385
  }
22191
22386
  if (!isSubagentPromptSubmit) {
22192
- promptClassification = classifyKeywordInput(prompt);
22387
+ teamNoticeTargetKey = parseTeamNoticeLedgerPrompt(prompt);
22193
22388
  }
22194
22389
  goalWorkflowAdditionalContext = allowGlobalSideEffects
22195
22390
  ? await buildCompletedGoalCleanupPromptWarning(cwd, prompt).catch(() => null)
@@ -22198,13 +22393,26 @@ export async function dispatchCodexNativeHook(
22198
22393
  ultragoalSteeringAdditionalContext = prompt && !isSubagentPromptSubmit && allowImplicitSessionSideEffects && allowGlobalSideEffects
22199
22394
  ? await applyUserPromptUltragoalSteering(cwd, prompt).catch((error) => `OMX native UserPromptSubmit rejected bounded .omx/ultragoal steering for G002-cli-and-prompt-submit-bridge: ${error instanceof Error ? error.message : String(error)}`)
22200
22395
  : null;
22201
- let suppressActivationSeeding = !allowImplicitSessionSideEffects;
22396
+ // An explicit independent payload session is safe to seed in its own
22397
+ // session-scoped state even when global side effects (HUD/root mirrors) are
22398
+ // suppressed because a stale selected pointer exists.
22399
+ let suppressActivationSeeding = !allowImplicitSessionSideEffects
22400
+ || (!allowGlobalSideEffects
22401
+ && promptTurnContext?.status !== "authorized");
22202
22402
  if (promptTurnContext?.status === "authorized") {
22203
22403
  sessionIdForState = promptTurnContext.authorization.targetSessionId;
22204
22404
  } else if (prompt && !isSubagentPromptSubmit && allowImplicitSessionSideEffects) {
22205
22405
  const rawHookSessionId = canonicalSessionId || nativeSessionId;
22206
22406
  const normalizedHookSessionId = normalizeSessionId(rawHookSessionId);
22207
- const explicitHookSessionId = currentSessionState ? undefined : normalizedHookSessionId;
22407
+ // An explicit payload session must win over a stale selected pointer.
22408
+ // Preserve the pointer only for its authenticated session/native alias;
22409
+ // otherwise seed state in the payload's session rather than silently
22410
+ // mutating the selected session.
22411
+ const explicitHookSessionId = currentSessionState
22412
+ && normalizedHookSessionId
22413
+ && payloadMatchesSessionPointer(normalizedHookSessionId, currentSessionState)
22414
+ ? undefined
22415
+ : normalizedHookSessionId;
22208
22416
  if (rawHookSessionId && !normalizedHookSessionId) {
22209
22417
  suppressActivationSeeding = true;
22210
22418
  } else {
@@ -22378,7 +22586,8 @@ export async function dispatchCodexNativeHook(
22378
22586
  allowTeamWorkerSideEffects: false,
22379
22587
  });
22380
22588
  }
22381
- if (hookEventName === "UserPromptSubmit" && !isSubagentPromptSubmit && teamNoticeTargetKey) {
22589
+ if (hookEventName === "UserPromptSubmit" && !isSubagentPromptSubmit && teamNoticeTargetKey
22590
+ && allowGlobalSideEffects) {
22382
22591
  const reconciled = await reconcileTeamNoticeLedger({ stateRoot: stateDir, targetKey: teamNoticeTargetKey }).catch(() => null);
22383
22592
  if (!reconciled || reconciled.context.length === 0) {
22384
22593
  teamNoticeAdditionalContext = "OMX invalidated this queued Team wake immediately before model input because no active source-proven Team notices remain. Do not infer or reference a removed Team from the generic wake.";
@@ -22411,16 +22620,17 @@ export async function dispatchCodexNativeHook(
22411
22620
  buildWikiPreCompactContext({ cwd });
22412
22621
  } else if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
22413
22622
  const additionalContext = hookEventName === "SessionStart"
22414
- ? await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId, {
22623
+ ? [await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId, {
22415
22624
  hookEventName,
22416
22625
  payload,
22417
22626
  canonicalSessionId,
22418
22627
  nativeSessionId: resolvedNativeSessionId || nativeSessionId,
22419
- })
22628
+ }), advisoryAdditionalContext].filter((entry): entry is string => Boolean(entry)).join("\n\n") || null
22420
22629
  : isSubagentPromptSubmit
22421
22630
  ? null
22422
22631
  : [
22423
22632
  teamNoticeAdditionalContext,
22633
+ advisoryAdditionalContext,
22424
22634
  promptClassification ? buildAdditionalContextMessage(promptClassification, skillState, cwd, payload) : null,
22425
22635
  ultragoalSteeringAdditionalContext,
22426
22636
  goalWorkflowAdditionalContext,
@@ -8,6 +8,7 @@ import {
8
8
  writeUserInstallStamp,
9
9
  } from './postinstall-advisory.js';
10
10
  import { getPackageRoot } from "../utils/package.js";
11
+ import { hydrateNativeBinary } from "../cli/native-assets.js";
11
12
 
12
13
  type PostinstallStatus =
13
14
  | "noop-local"
@@ -24,10 +25,40 @@ interface PostinstallDependencies {
24
25
  env: NodeJS.ProcessEnv;
25
26
  getCurrentVersion: () => Promise<string | null>;
26
27
  log: (message: string) => void;
28
+ hydrateRuntime: () => Promise<string | undefined>;
27
29
  readStamp: () => Promise<UserInstallStamp | null>;
28
30
  writeStamp: (stamp: UserInstallStamp) => Promise<void>;
29
31
  }
30
32
 
33
+ const RUNTIME_HYDRATION_TIMEOUT_MS = 15_000;
34
+
35
+ export async function hydrateOmxRuntimeNonFatal(options: {
36
+ packageRoot?: string;
37
+ env?: NodeJS.ProcessEnv;
38
+ log?: (message: string) => void;
39
+ timeoutMs?: number;
40
+ } = {}): Promise<string | undefined> {
41
+ const log = options.log ?? ((message: string) => console.log(message));
42
+ const controller = new AbortController();
43
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? RUNTIME_HYDRATION_TIMEOUT_MS);
44
+ timer.unref?.();
45
+ try {
46
+ const runtimePath = await hydrateNativeBinary("omx-runtime", {
47
+ packageRoot: options.packageRoot,
48
+ env: options.env,
49
+ signal: controller.signal,
50
+ });
51
+ if (runtimePath) log(`[omx] Hydrated omx-runtime for this platform: ${runtimePath}`);
52
+ else log("[omx] omx-runtime was not available for this platform; native runtime features remain disabled.");
53
+ return runtimePath;
54
+ } catch (error) {
55
+ log(`[omx] omx-runtime hydration failed non-fatally: ${error instanceof Error ? error.message : String(error)}`);
56
+ return undefined;
57
+ } finally {
58
+ clearTimeout(timer);
59
+ }
60
+ }
61
+
31
62
  function stripLeadingV(version: string): string {
32
63
  return version.trim().replace(/^v/i, "");
33
64
  }
@@ -55,6 +86,7 @@ const defaultDependencies: PostinstallDependencies = {
55
86
  env: process.env,
56
87
  getCurrentVersion,
57
88
  log: (message) => console.log(message),
89
+ hydrateRuntime: () => hydrateOmxRuntimeNonFatal(),
58
90
  readStamp: () => readUserInstallStamp(),
59
91
  writeStamp: (stamp) => writeUserInstallStamp(stamp),
60
92
  };
@@ -75,6 +107,20 @@ export async function runPostinstall(
75
107
  }
76
108
 
77
109
  const currentStampVersion = stripLeadingV(currentVersion);
110
+ try {
111
+ const runtimePath = await resolved.hydrateRuntime();
112
+ if (runtimePath) {
113
+ resolved.log(`[omx] Hydrated omx-runtime for this platform: ${runtimePath}`);
114
+ } else {
115
+ resolved.log(
116
+ "[omx] omx-runtime was not available for this platform; native runtime features remain disabled.",
117
+ );
118
+ }
119
+ } catch (error) {
120
+ resolved.log(
121
+ `[omx] omx-runtime hydration failed non-fatally: ${error instanceof Error ? error.message : String(error)}`,
122
+ );
123
+ }
78
124
  const existingStamp = await resolved.readStamp();
79
125
  if (!isInstallVersionBump(currentVersion, existingStamp)) {
80
126
  return { status: "noop-same-version", version: currentStampVersion };