oh-my-codex 0.20.2 → 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 (805) hide show
  1. package/Cargo.lock +36 -18
  2. package/Cargo.toml +1 -1
  3. package/README.md +28 -2
  4. package/crates/omx-runtime/Cargo.toml +4 -0
  5. package/crates/omx-runtime/src/main.rs +415 -2
  6. package/crates/omx-runtime/tests/execution.rs +483 -0
  7. package/crates/omx-runtime-core/src/dispatch.rs +96 -10
  8. package/crates/omx-runtime-core/src/engine.rs +839 -29
  9. package/crates/omx-runtime-core/src/lib.rs +8 -0
  10. package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
  11. package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
  12. package/dist/adapt/__tests__/herdr-target.test.js +72 -0
  13. package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
  14. package/dist/adapt/contracts.d.ts +1 -1
  15. package/dist/adapt/contracts.d.ts.map +1 -1
  16. package/dist/adapt/contracts.js +1 -1
  17. package/dist/adapt/contracts.js.map +1 -1
  18. package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
  19. package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
  20. package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
  21. package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
  22. package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
  23. package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
  24. package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
  25. package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
  26. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
  27. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
  28. package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
  29. package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
  30. package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
  31. package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
  32. package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
  33. package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
  34. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
  35. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
  36. package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
  37. package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
  38. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
  39. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
  40. package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
  41. package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
  42. package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
  43. package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
  44. package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
  45. package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
  46. package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
  47. package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
  48. package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
  49. package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
  50. package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
  51. package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
  52. package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
  53. package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
  54. package/dist/adapt/herdr/authority.d.ts +34 -0
  55. package/dist/adapt/herdr/authority.d.ts.map +1 -0
  56. package/dist/adapt/herdr/authority.js +71 -0
  57. package/dist/adapt/herdr/authority.js.map +1 -0
  58. package/dist/adapt/herdr/bridge.d.ts +84 -0
  59. package/dist/adapt/herdr/bridge.d.ts.map +1 -0
  60. package/dist/adapt/herdr/bridge.js +222 -0
  61. package/dist/adapt/herdr/bridge.js.map +1 -0
  62. package/dist/adapt/herdr/sanitize.d.ts +20 -0
  63. package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
  64. package/dist/adapt/herdr/sanitize.js +70 -0
  65. package/dist/adapt/herdr/sanitize.js.map +1 -0
  66. package/dist/adapt/herdr/semantic.d.ts +67 -0
  67. package/dist/adapt/herdr/semantic.d.ts.map +1 -0
  68. package/dist/adapt/herdr/semantic.js +170 -0
  69. package/dist/adapt/herdr/semantic.js.map +1 -0
  70. package/dist/adapt/herdr/seq-store.d.ts +32 -0
  71. package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
  72. package/dist/adapt/herdr/seq-store.js +126 -0
  73. package/dist/adapt/herdr/seq-store.js.map +1 -0
  74. package/dist/adapt/herdr/team-map.d.ts +30 -0
  75. package/dist/adapt/herdr/team-map.d.ts.map +1 -0
  76. package/dist/adapt/herdr/team-map.js +37 -0
  77. package/dist/adapt/herdr/team-map.js.map +1 -0
  78. package/dist/adapt/herdr/transport.d.ts +115 -0
  79. package/dist/adapt/herdr/transport.d.ts.map +1 -0
  80. package/dist/adapt/herdr/transport.js +260 -0
  81. package/dist/adapt/herdr/transport.js.map +1 -0
  82. package/dist/adapt/herdr/wiring.d.ts +24 -0
  83. package/dist/adapt/herdr/wiring.d.ts.map +1 -0
  84. package/dist/adapt/herdr/wiring.js +62 -0
  85. package/dist/adapt/herdr/wiring.js.map +1 -0
  86. package/dist/adapt/herdr.d.ts +19 -0
  87. package/dist/adapt/herdr.d.ts.map +1 -0
  88. package/dist/adapt/herdr.js +115 -0
  89. package/dist/adapt/herdr.js.map +1 -0
  90. package/dist/adapt/index.d.ts +4 -0
  91. package/dist/adapt/index.d.ts.map +1 -1
  92. package/dist/adapt/index.js +48 -0
  93. package/dist/adapt/index.js.map +1 -1
  94. package/dist/adapt/registry.d.ts.map +1 -1
  95. package/dist/adapt/registry.js +11 -0
  96. package/dist/adapt/registry.js.map +1 -1
  97. package/dist/agents/__tests__/definitions.test.js +81 -0
  98. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  99. package/dist/agents/__tests__/native-config.test.js +25 -0
  100. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  101. package/dist/agents/native-config.d.ts +2 -1
  102. package/dist/agents/native-config.d.ts.map +1 -1
  103. package/dist/agents/native-config.js.map +1 -1
  104. package/dist/auth/__tests__/hotswap.test.js +60 -1
  105. package/dist/auth/__tests__/hotswap.test.js.map +1 -1
  106. package/dist/auth/__tests__/storage.test.js +33 -1
  107. package/dist/auth/__tests__/storage.test.js.map +1 -1
  108. package/dist/auth/hotswap.d.ts +22 -2
  109. package/dist/auth/hotswap.d.ts.map +1 -1
  110. package/dist/auth/hotswap.js +107 -22
  111. package/dist/auth/hotswap.js.map +1 -1
  112. package/dist/auth/storage.js +1 -1
  113. package/dist/auth/storage.js.map +1 -1
  114. package/dist/autopilot/__tests__/ralplan-gate.test.js +86 -1333
  115. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
  116. package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
  117. package/dist/autopilot/ralplan-gate.js +7 -6
  118. package/dist/autopilot/ralplan-gate.js.map +1 -1
  119. package/dist/cli/__tests__/agents-init.test.js +4 -23
  120. package/dist/cli/__tests__/agents-init.test.js.map +1 -1
  121. package/dist/cli/__tests__/api.test.js +61 -24
  122. package/dist/cli/__tests__/api.test.js.map +1 -1
  123. package/dist/cli/__tests__/auth.test.js +63 -7
  124. package/dist/cli/__tests__/auth.test.js.map +1 -1
  125. package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
  126. package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
  127. package/dist/cli/__tests__/codex-plugin-layout.test.js +150 -2
  128. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  129. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
  130. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
  131. package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
  132. package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
  133. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
  134. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
  135. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
  136. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
  137. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
  138. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
  139. package/dist/cli/__tests__/doctor-state-root-binding.test.js +139 -0
  140. package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
  141. package/dist/cli/__tests__/doctor-warning-copy.test.js +135 -1
  142. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  143. package/dist/cli/__tests__/exec.test.js +211 -0
  144. package/dist/cli/__tests__/exec.test.js.map +1 -1
  145. package/dist/cli/__tests__/index.test.js +878 -463
  146. package/dist/cli/__tests__/index.test.js.map +1 -1
  147. package/dist/cli/__tests__/launch-fallback.test.js +1290 -127
  148. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  149. package/dist/cli/__tests__/mcp-parity.test.js +8 -4
  150. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  151. package/dist/cli/__tests__/native-assets.test.js +398 -16
  152. package/dist/cli/__tests__/native-assets.test.js.map +1 -1
  153. package/dist/cli/__tests__/native-hook-claim-journal.test.js +132 -6
  154. package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
  155. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +3 -3
  156. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  157. package/dist/cli/__tests__/ralph.test.js +3 -3
  158. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  159. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +49 -164
  160. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
  161. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
  162. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
  163. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
  164. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
  165. package/dist/cli/__tests__/ralplan.test.js +107 -109
  166. package/dist/cli/__tests__/ralplan.test.js.map +1 -1
  167. package/dist/cli/__tests__/resume.test.js +11 -10
  168. package/dist/cli/__tests__/resume.test.js.map +1 -1
  169. package/dist/cli/__tests__/session-scoped-runtime.test.js +1118 -43
  170. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  171. package/dist/cli/__tests__/session-search-help.test.js +25 -1
  172. package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
  173. package/dist/cli/__tests__/setup-agents-overwrite.test.js +8 -55
  174. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  175. package/dist/cli/__tests__/setup-install-mode.test.js +224 -7
  176. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  177. package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
  178. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  179. package/dist/cli/__tests__/team.test.js +150 -8
  180. package/dist/cli/__tests__/team.test.js.map +1 -1
  181. package/dist/cli/__tests__/ultragoal.test.js +117 -2
  182. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  183. package/dist/cli/__tests__/uninstall.test.js +95 -4
  184. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  185. package/dist/cli/__tests__/update.test.js +669 -177
  186. package/dist/cli/__tests__/update.test.js.map +1 -1
  187. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +33 -2
  188. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  189. package/dist/cli/api.d.ts.map +1 -1
  190. package/dist/cli/api.js +9 -10
  191. package/dist/cli/api.js.map +1 -1
  192. package/dist/cli/codex-feature-probe.d.ts +16 -0
  193. package/dist/cli/codex-feature-probe.d.ts.map +1 -1
  194. package/dist/cli/codex-feature-probe.js +44 -0
  195. package/dist/cli/codex-feature-probe.js.map +1 -1
  196. package/dist/cli/codex-home.d.ts.map +1 -1
  197. package/dist/cli/codex-home.js +7 -4
  198. package/dist/cli/codex-home.js.map +1 -1
  199. package/dist/cli/doctor.d.ts +20 -0
  200. package/dist/cli/doctor.d.ts.map +1 -1
  201. package/dist/cli/doctor.js +290 -3
  202. package/dist/cli/doctor.js.map +1 -1
  203. package/dist/cli/index.d.ts +234 -12
  204. package/dist/cli/index.d.ts.map +1 -1
  205. package/dist/cli/index.js +2409 -746
  206. package/dist/cli/index.js.map +1 -1
  207. package/dist/cli/mcp-parity.js +2 -2
  208. package/dist/cli/mcp-parity.js.map +1 -1
  209. package/dist/cli/native-assets.d.ts +25 -0
  210. package/dist/cli/native-assets.d.ts.map +1 -1
  211. package/dist/cli/native-assets.js +448 -51
  212. package/dist/cli/native-assets.js.map +1 -1
  213. package/dist/cli/native-hook-claim-journal.d.ts +20 -5
  214. package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
  215. package/dist/cli/native-hook-claim-journal.js +67 -32
  216. package/dist/cli/native-hook-claim-journal.js.map +1 -1
  217. package/dist/cli/package-manager-ownership.d.ts +63 -0
  218. package/dist/cli/package-manager-ownership.d.ts.map +1 -0
  219. package/dist/cli/package-manager-ownership.js +323 -0
  220. package/dist/cli/package-manager-ownership.js.map +1 -0
  221. package/dist/cli/ralph.js +2 -2
  222. package/dist/cli/ralph.js.map +1 -1
  223. package/dist/cli/ralplan.d.ts +5 -7
  224. package/dist/cli/ralplan.d.ts.map +1 -1
  225. package/dist/cli/ralplan.js +83 -134
  226. package/dist/cli/ralplan.js.map +1 -1
  227. package/dist/cli/session-search.d.ts +5 -0
  228. package/dist/cli/session-search.d.ts.map +1 -1
  229. package/dist/cli/session-search.js +87 -0
  230. package/dist/cli/session-search.js.map +1 -1
  231. package/dist/cli/setup-preferences.d.ts +15 -0
  232. package/dist/cli/setup-preferences.d.ts.map +1 -1
  233. package/dist/cli/setup-preferences.js +27 -1
  234. package/dist/cli/setup-preferences.js.map +1 -1
  235. package/dist/cli/setup.d.ts +8 -0
  236. package/dist/cli/setup.d.ts.map +1 -1
  237. package/dist/cli/setup.js +119 -47
  238. package/dist/cli/setup.js.map +1 -1
  239. package/dist/cli/sparkshell.d.ts.map +1 -1
  240. package/dist/cli/sparkshell.js +52 -9
  241. package/dist/cli/sparkshell.js.map +1 -1
  242. package/dist/cli/ultragoal.d.ts.map +1 -1
  243. package/dist/cli/ultragoal.js +2 -2
  244. package/dist/cli/ultragoal.js.map +1 -1
  245. package/dist/cli/uninstall.d.ts +9 -0
  246. package/dist/cli/uninstall.d.ts.map +1 -1
  247. package/dist/cli/uninstall.js +71 -30
  248. package/dist/cli/uninstall.js.map +1 -1
  249. package/dist/cli/update-worker.d.ts +2 -0
  250. package/dist/cli/update-worker.d.ts.map +1 -0
  251. package/dist/cli/update-worker.js +142 -0
  252. package/dist/cli/update-worker.js.map +1 -0
  253. package/dist/cli/update.d.ts +14 -22
  254. package/dist/cli/update.d.ts.map +1 -1
  255. package/dist/cli/update.js +192 -241
  256. package/dist/cli/update.js.map +1 -1
  257. package/dist/compat/__tests__/rust-runtime-compat.test.js +1 -1
  258. package/dist/config/__tests__/generator-idempotent.test.js +503 -30
  259. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  260. package/dist/config/__tests__/generator-notify.test.js +5 -3
  261. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  262. package/dist/config/__tests__/models.test.js +67 -3
  263. package/dist/config/__tests__/models.test.js.map +1 -1
  264. package/dist/config/generator.d.ts +27 -21
  265. package/dist/config/generator.d.ts.map +1 -1
  266. package/dist/config/generator.js +610 -152
  267. package/dist/config/generator.js.map +1 -1
  268. package/dist/config/models.d.ts +12 -2
  269. package/dist/config/models.d.ts.map +1 -1
  270. package/dist/config/models.js +15 -1
  271. package/dist/config/models.js.map +1 -1
  272. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
  273. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  274. package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
  275. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  276. package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
  277. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  278. package/dist/hooks/__tests__/agents-overlay.test.js +5 -3
  279. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  280. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -4
  281. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  282. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
  283. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
  284. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +172 -0
  285. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
  286. package/dist/hooks/__tests__/keyword-detector.test.js +176 -37
  287. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  288. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +402 -545
  289. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  290. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +39 -4
  291. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  292. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +161 -26
  293. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  294. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
  295. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  296. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
  297. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
  298. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
  299. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  300. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +533 -14
  301. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  302. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +159 -24
  303. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  304. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +482 -32
  305. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  306. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
  307. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
  308. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +68 -1
  309. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  310. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +7 -1
  311. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
  312. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +44 -4
  313. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  314. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +9 -0
  315. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
  316. package/dist/hooks/__tests__/session.test.js +3130 -365
  317. package/dist/hooks/__tests__/session.test.js.map +1 -1
  318. package/dist/hooks/agents-overlay.js +1 -1
  319. package/dist/hooks/agents-overlay.js.map +1 -1
  320. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
  321. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  322. package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
  323. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
  324. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  325. package/dist/hooks/extensibility/dispatcher.js +20 -3
  326. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  327. package/dist/hooks/extensibility/plugin-runner.js +1 -0
  328. package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
  329. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  330. package/dist/hooks/extensibility/runtime.js.map +1 -1
  331. package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
  332. package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
  333. package/dist/hooks/extensibility/sdk/paths.js +2 -2
  334. package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
  335. package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
  336. package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
  337. package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
  338. package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
  339. package/dist/hooks/extensibility/sdk.d.ts +1 -0
  340. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  341. package/dist/hooks/extensibility/sdk.js +1 -1
  342. package/dist/hooks/extensibility/sdk.js.map +1 -1
  343. package/dist/hooks/extensibility/types.d.ts +7 -0
  344. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  345. package/dist/hooks/keyword-detector.d.ts +10 -3
  346. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  347. package/dist/hooks/keyword-detector.js +116 -20
  348. package/dist/hooks/keyword-detector.js.map +1 -1
  349. package/dist/hooks/session.d.ts +204 -14
  350. package/dist/hooks/session.d.ts.map +1 -1
  351. package/dist/hooks/session.js +1500 -223
  352. package/dist/hooks/session.js.map +1 -1
  353. package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
  354. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  355. package/dist/hud/__tests__/index.test.js +26 -16
  356. package/dist/hud/__tests__/index.test.js.map +1 -1
  357. package/dist/hud/__tests__/reconcile.test.js +83 -78
  358. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  359. package/dist/hud/__tests__/state.test.js +36 -31
  360. package/dist/hud/__tests__/state.test.js.map +1 -1
  361. package/dist/hud/__tests__/tmux.test.js +155 -198
  362. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  363. package/dist/hud/tmux.d.ts +42 -4
  364. package/dist/hud/tmux.d.ts.map +1 -1
  365. package/dist/hud/tmux.js +1017 -139
  366. package/dist/hud/tmux.js.map +1 -1
  367. package/dist/leader/__tests__/contract.test.js +124 -37
  368. package/dist/leader/__tests__/contract.test.js.map +1 -1
  369. package/dist/leader/contract.d.ts +17 -6
  370. package/dist/leader/contract.d.ts.map +1 -1
  371. package/dist/leader/contract.js +102 -26
  372. package/dist/leader/contract.js.map +1 -1
  373. package/dist/mcp/__tests__/code-intel-server.test.js +31 -3
  374. package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
  375. package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
  376. package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
  377. package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
  378. package/dist/mcp/__tests__/state-paths.test.js +735 -4
  379. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  380. package/dist/mcp/__tests__/state-server.test.js +1 -1
  381. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  382. package/dist/mcp/__tests__/trace-server.test.js +2 -2
  383. package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
  384. package/dist/mcp/__tests__/wiki-server.test.js +18 -0
  385. package/dist/mcp/__tests__/wiki-server.test.js.map +1 -1
  386. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  387. package/dist/mcp/code-intel-server.js +13 -3
  388. package/dist/mcp/code-intel-server.js.map +1 -1
  389. package/dist/mcp/hermes-bridge.d.ts.map +1 -1
  390. package/dist/mcp/hermes-bridge.js +2 -2
  391. package/dist/mcp/hermes-bridge.js.map +1 -1
  392. package/dist/mcp/state-paths.d.ts +78 -4
  393. package/dist/mcp/state-paths.d.ts.map +1 -1
  394. package/dist/mcp/state-paths.js +543 -40
  395. package/dist/mcp/state-paths.js.map +1 -1
  396. package/dist/mcp/state-server.d.ts +4 -4
  397. package/dist/mcp/state-server.d.ts.map +1 -1
  398. package/dist/mcp/wiki-server.d.ts +11 -0
  399. package/dist/mcp/wiki-server.d.ts.map +1 -1
  400. package/dist/mcp/wiki-server.js +9 -2
  401. package/dist/mcp/wiki-server.js.map +1 -1
  402. package/dist/modes/__tests__/base-autopilot-gates.test.js +36 -7
  403. package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
  404. package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -1
  405. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
  406. package/dist/modes/__tests__/base-session-scope.test.js +17 -8
  407. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  408. package/dist/modes/__tests__/base-tmux-pane.test.js +4 -4
  409. package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
  410. package/dist/modes/base.d.ts +5 -5
  411. package/dist/modes/base.d.ts.map +1 -1
  412. package/dist/modes/base.js +76 -21
  413. package/dist/modes/base.js.map +1 -1
  414. package/dist/native-assets/archive.d.ts +17 -0
  415. package/dist/native-assets/archive.d.ts.map +1 -0
  416. package/dist/native-assets/archive.js +238 -0
  417. package/dist/native-assets/archive.js.map +1 -0
  418. package/dist/native-assets/policy.d.ts +42 -0
  419. package/dist/native-assets/policy.d.ts.map +1 -0
  420. package/dist/native-assets/policy.js +155 -0
  421. package/dist/native-assets/policy.js.map +1 -0
  422. package/dist/notifications/temp-contract.d.ts.map +1 -1
  423. package/dist/notifications/temp-contract.js +4 -0
  424. package/dist/notifications/temp-contract.js.map +1 -1
  425. package/dist/pipeline/__tests__/orchestrator.test.js +164 -42
  426. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  427. package/dist/pipeline/__tests__/stages.test.js +72 -155
  428. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  429. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  430. package/dist/pipeline/orchestrator.js +124 -18
  431. package/dist/pipeline/orchestrator.js.map +1 -1
  432. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  433. package/dist/pipeline/stages/ralplan.js +36 -8
  434. package/dist/pipeline/stages/ralplan.js.map +1 -1
  435. package/dist/ralplan/__tests__/consensus-gate.test.js +73 -1316
  436. package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
  437. package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts +2 -0
  438. package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts.map +1 -0
  439. package/dist/ralplan/__tests__/documented-leader-preflight.test.js +335 -0
  440. package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -0
  441. package/dist/ralplan/__tests__/runtime.test.js +85 -101
  442. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  443. package/dist/ralplan/consensus-gate.d.ts +9 -1
  444. package/dist/ralplan/consensus-gate.d.ts.map +1 -1
  445. package/dist/ralplan/consensus-gate.js +82 -338
  446. package/dist/ralplan/consensus-gate.js.map +1 -1
  447. package/dist/ralplan/documented-leader-preflight.d.ts +41 -0
  448. package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -0
  449. package/dist/ralplan/documented-leader-preflight.js +360 -0
  450. package/dist/ralplan/documented-leader-preflight.js.map +1 -0
  451. package/dist/ralplan/runtime.d.ts +2 -1
  452. package/dist/ralplan/runtime.d.ts.map +1 -1
  453. package/dist/ralplan/runtime.js +67 -168
  454. package/dist/ralplan/runtime.js.map +1 -1
  455. package/dist/runtime/__tests__/bridge.test.js +42 -1
  456. package/dist/runtime/__tests__/bridge.test.js.map +1 -1
  457. package/dist/runtime/bridge.d.ts +12 -0
  458. package/dist/runtime/bridge.d.ts.map +1 -1
  459. package/dist/runtime/bridge.js +52 -1
  460. package/dist/runtime/bridge.js.map +1 -1
  461. package/dist/runtime/run-state.d.ts +5 -1
  462. package/dist/runtime/run-state.d.ts.map +1 -1
  463. package/dist/runtime/run-state.js +15 -8
  464. package/dist/runtime/run-state.js.map +1 -1
  465. package/dist/scripts/__tests__/codex-native-hook.test.js +16323 -8978
  466. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  467. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
  468. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
  469. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +225 -0
  470. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
  471. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
  472. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
  473. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
  474. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
  475. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
  476. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
  477. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +259 -0
  478. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
  479. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
  480. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
  481. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +491 -0
  482. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
  483. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
  484. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
  485. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +708 -0
  486. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
  487. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
  488. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
  489. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +208 -0
  490. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
  491. package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
  492. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
  493. package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
  494. package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
  495. package/dist/scripts/__tests__/postinstall.test.js +19 -1
  496. package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
  497. package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts +2 -0
  498. package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts.map +1 -0
  499. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +108 -0
  500. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -0
  501. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +63 -173
  502. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
  503. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +74 -159
  504. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
  505. package/dist/scripts/__tests__/smoke-packed-install.test.js +404 -13
  506. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  507. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
  508. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
  509. package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
  510. package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
  511. package/dist/scripts/codex-native-hook.d.ts +53 -1
  512. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  513. package/dist/scripts/codex-native-hook.js +14448 -1480
  514. package/dist/scripts/codex-native-hook.js.map +1 -1
  515. package/dist/scripts/codex-native-pre-post.d.ts +9 -0
  516. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  517. package/dist/scripts/codex-native-pre-post.js +35 -12
  518. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  519. package/dist/scripts/generate-native-release-manifest.js +80 -51
  520. package/dist/scripts/generate-native-release-manifest.js.map +1 -1
  521. package/dist/scripts/notify-fallback-watcher.js +78 -115
  522. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  523. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  524. package/dist/scripts/notify-hook/auto-nudge.js +74 -3
  525. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  526. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  527. package/dist/scripts/notify-hook/state-io.js +5 -0
  528. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  529. package/dist/scripts/notify-hook/team-dispatch.d.ts +9 -0
  530. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  531. package/dist/scripts/notify-hook/team-dispatch.js +234 -79
  532. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  533. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  534. package/dist/scripts/notify-hook/team-leader-nudge.js +71 -16
  535. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  536. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +12 -4
  537. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  538. package/dist/scripts/notify-hook/team-tmux-guard.js +365 -44
  539. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  540. package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
  541. package/dist/scripts/notify-hook/team-worker-stop.js +42 -21
  542. package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
  543. package/dist/scripts/notify-hook/team-worker.d.ts +3 -0
  544. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  545. package/dist/scripts/notify-hook/team-worker.js +82 -33
  546. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  547. package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
  548. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  549. package/dist/scripts/notify-hook/tmux-injection.js +32 -3
  550. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  551. package/dist/scripts/notify-hook.js +79 -82
  552. package/dist/scripts/notify-hook.js.map +1 -1
  553. package/dist/scripts/postinstall-advisory.d.ts +14 -0
  554. package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
  555. package/dist/scripts/postinstall-advisory.js +49 -0
  556. package/dist/scripts/postinstall-advisory.js.map +1 -0
  557. package/dist/scripts/postinstall.d.ts +1 -1
  558. package/dist/scripts/postinstall.d.ts.map +1 -1
  559. package/dist/scripts/postinstall.js +1 -1
  560. package/dist/scripts/postinstall.js.map +1 -1
  561. package/dist/scripts/smoke-packed-install.d.ts +80 -4
  562. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  563. package/dist/scripts/smoke-packed-install.js +3162 -26
  564. package/dist/scripts/smoke-packed-install.js.map +1 -1
  565. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  566. package/dist/scripts/sync-plugin-mirror.js +16 -1
  567. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  568. package/dist/scripts/verify-native-release-assets.js +37 -23
  569. package/dist/scripts/verify-native-release-assets.js.map +1 -1
  570. package/dist/state/__tests__/mode-state-context.test.js +61 -0
  571. package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
  572. package/dist/state/__tests__/operations.test.js +462 -850
  573. package/dist/state/__tests__/operations.test.js.map +1 -1
  574. package/dist/state/__tests__/skill-active.test.js +400 -2
  575. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  576. package/dist/state/mode-state-context.d.ts +8 -0
  577. package/dist/state/mode-state-context.d.ts.map +1 -1
  578. package/dist/state/mode-state-context.js +73 -0
  579. package/dist/state/mode-state-context.js.map +1 -1
  580. package/dist/state/operations.d.ts +3 -0
  581. package/dist/state/operations.d.ts.map +1 -1
  582. package/dist/state/operations.js +144 -40
  583. package/dist/state/operations.js.map +1 -1
  584. package/dist/state/skill-active.d.ts +18 -1
  585. package/dist/state/skill-active.d.ts.map +1 -1
  586. package/dist/state/skill-active.js +420 -23
  587. package/dist/state/skill-active.js.map +1 -1
  588. package/dist/state/workflow-transition-reconcile.d.ts +3 -0
  589. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  590. package/dist/state/workflow-transition-reconcile.js +10 -4
  591. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  592. package/dist/state/workflow-transition.d.ts.map +1 -1
  593. package/dist/state/workflow-transition.js +3 -1
  594. package/dist/state/workflow-transition.js.map +1 -1
  595. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +53 -247
  596. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
  597. package/dist/subagents/__tests__/tracker.test.js +837 -1048
  598. package/dist/subagents/__tests__/tracker.test.js.map +1 -1
  599. package/dist/subagents/tracker.d.ts +58 -135
  600. package/dist/subagents/tracker.d.ts.map +1 -1
  601. package/dist/subagents/tracker.js +811 -632
  602. package/dist/subagents/tracker.js.map +1 -1
  603. package/dist/team/__tests__/api-interop.test.js +91 -1
  604. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  605. package/dist/team/__tests__/delivery-e2e-smoke.test.js +58 -17
  606. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
  607. package/dist/team/__tests__/idle-nudge.test.js +45 -15
  608. package/dist/team/__tests__/idle-nudge.test.js.map +1 -1
  609. package/dist/team/__tests__/mcp-comm.test.js +197 -30
  610. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  611. package/dist/team/__tests__/model-contract.test.js +110 -3
  612. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  613. package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
  614. package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
  615. package/dist/team/__tests__/notice-ledger.test.js +131 -0
  616. package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
  617. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
  618. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
  619. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
  620. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
  621. package/dist/team/__tests__/phase-controller.test.js +20 -0
  622. package/dist/team/__tests__/phase-controller.test.js.map +1 -1
  623. package/dist/team/__tests__/runtime-cli.test.js +9 -0
  624. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  625. package/dist/team/__tests__/runtime.test.js +3963 -428
  626. package/dist/team/__tests__/runtime.test.js.map +1 -1
  627. package/dist/team/__tests__/scaling.test.js +2405 -203
  628. package/dist/team/__tests__/scaling.test.js.map +1 -1
  629. package/dist/team/__tests__/state-root.test.js +117 -2
  630. package/dist/team/__tests__/state-root.test.js.map +1 -1
  631. package/dist/team/__tests__/state.test.js +804 -36
  632. package/dist/team/__tests__/state.test.js.map +1 -1
  633. package/dist/team/__tests__/team-ops-contract.test.js +6 -0
  634. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
  635. package/dist/team/__tests__/tmux-session.test.js +4099 -1039
  636. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  637. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
  638. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
  639. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +149 -0
  640. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
  641. package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
  642. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
  643. package/dist/team/__tests__/tmux-test-fixture.js +242 -15
  644. package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
  645. package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
  646. package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
  647. package/dist/team/__tests__/worker-runtime-identity.test.js +53 -44
  648. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  649. package/dist/team/__tests__/worktree.test.js +6 -0
  650. package/dist/team/__tests__/worktree.test.js.map +1 -1
  651. package/dist/team/api-interop.d.ts.map +1 -1
  652. package/dist/team/api-interop.js +15 -9
  653. package/dist/team/api-interop.js.map +1 -1
  654. package/dist/team/exact-pane.d.ts +23 -0
  655. package/dist/team/exact-pane.d.ts.map +1 -0
  656. package/dist/team/exact-pane.js +133 -0
  657. package/dist/team/exact-pane.js.map +1 -0
  658. package/dist/team/idle-nudge.d.ts +12 -1
  659. package/dist/team/idle-nudge.d.ts.map +1 -1
  660. package/dist/team/idle-nudge.js +41 -14
  661. package/dist/team/idle-nudge.js.map +1 -1
  662. package/dist/team/model-contract.d.ts +2 -5
  663. package/dist/team/model-contract.d.ts.map +1 -1
  664. package/dist/team/model-contract.js +59 -17
  665. package/dist/team/model-contract.js.map +1 -1
  666. package/dist/team/notice-ledger.d.ts +54 -0
  667. package/dist/team/notice-ledger.d.ts.map +1 -0
  668. package/dist/team/notice-ledger.js +259 -0
  669. package/dist/team/notice-ledger.js.map +1 -0
  670. package/dist/team/phase-controller.d.ts.map +1 -1
  671. package/dist/team/phase-controller.js +2 -0
  672. package/dist/team/phase-controller.js.map +1 -1
  673. package/dist/team/runtime.d.ts +4 -1
  674. package/dist/team/runtime.d.ts.map +1 -1
  675. package/dist/team/runtime.js +1527 -291
  676. package/dist/team/runtime.js.map +1 -1
  677. package/dist/team/scaling.d.ts +13 -1
  678. package/dist/team/scaling.d.ts.map +1 -1
  679. package/dist/team/scaling.js +1503 -387
  680. package/dist/team/scaling.js.map +1 -1
  681. package/dist/team/state/dispatch.d.ts.map +1 -1
  682. package/dist/team/state/dispatch.js +26 -8
  683. package/dist/team/state/dispatch.js.map +1 -1
  684. package/dist/team/state/locks.d.ts.map +1 -1
  685. package/dist/team/state/locks.js +61 -13
  686. package/dist/team/state/locks.js.map +1 -1
  687. package/dist/team/state/monitor.d.ts +10 -0
  688. package/dist/team/state/monitor.d.ts.map +1 -1
  689. package/dist/team/state/monitor.js +13 -0
  690. package/dist/team/state/monitor.js.map +1 -1
  691. package/dist/team/state/tasks.d.ts.map +1 -1
  692. package/dist/team/state/tasks.js +4 -3
  693. package/dist/team/state/tasks.js.map +1 -1
  694. package/dist/team/state/types.d.ts +15 -0
  695. package/dist/team/state/types.d.ts.map +1 -1
  696. package/dist/team/state/types.js.map +1 -1
  697. package/dist/team/state-root.d.ts +12 -0
  698. package/dist/team/state-root.d.ts.map +1 -1
  699. package/dist/team/state-root.js +177 -0
  700. package/dist/team/state-root.js.map +1 -1
  701. package/dist/team/state.d.ts +85 -1
  702. package/dist/team/state.d.ts.map +1 -1
  703. package/dist/team/state.js +672 -129
  704. package/dist/team/state.js.map +1 -1
  705. package/dist/team/team-ops.d.ts +5 -0
  706. package/dist/team/team-ops.d.ts.map +1 -1
  707. package/dist/team/team-ops.js +4 -0
  708. package/dist/team/team-ops.js.map +1 -1
  709. package/dist/team/tmux-session.d.ts +163 -27
  710. package/dist/team/tmux-session.d.ts.map +1 -1
  711. package/dist/team/tmux-session.js +1682 -376
  712. package/dist/team/tmux-session.js.map +1 -1
  713. package/dist/team/worktree.d.ts.map +1 -1
  714. package/dist/team/worktree.js +4 -0
  715. package/dist/team/worktree.js.map +1 -1
  716. package/dist/ultragoal/__tests__/artifacts.test.js +950 -2
  717. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  718. package/dist/ultragoal/__tests__/docs-contract.test.js +1 -0
  719. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  720. package/dist/ultragoal/artifacts.d.ts +35 -1
  721. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  722. package/dist/ultragoal/artifacts.js +232 -46
  723. package/dist/ultragoal/artifacts.js.map +1 -1
  724. package/dist/utils/__tests__/file-durability.test.d.ts +2 -0
  725. package/dist/utils/__tests__/file-durability.test.d.ts.map +1 -0
  726. package/dist/utils/__tests__/file-durability.test.js +114 -0
  727. package/dist/utils/__tests__/file-durability.test.js.map +1 -0
  728. package/dist/utils/__tests__/paths.test.js +21 -1
  729. package/dist/utils/__tests__/paths.test.js.map +1 -1
  730. package/dist/utils/file-durability.d.ts +25 -0
  731. package/dist/utils/file-durability.d.ts.map +1 -0
  732. package/dist/utils/file-durability.js +67 -0
  733. package/dist/utils/file-durability.js.map +1 -0
  734. package/dist/utils/paths.d.ts.map +1 -1
  735. package/dist/utils/paths.js +14 -6
  736. package/dist/utils/paths.js.map +1 -1
  737. package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
  738. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  739. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +3 -0
  740. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
  741. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
  742. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
  743. package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
  744. package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
  745. package/dist/wiki/lint.d.ts +4 -1
  746. package/dist/wiki/lint.d.ts.map +1 -1
  747. package/dist/wiki/lint.js +3 -2
  748. package/dist/wiki/lint.js.map +1 -1
  749. package/package.json +13 -5
  750. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  751. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +105 -17
  752. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +13 -5
  753. package/plugins/oh-my-codex/skills/cancel/SKILL.md +30 -85
  754. package/plugins/oh-my-codex/skills/ralph/SKILL.md +6 -4
  755. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +16 -17
  756. package/plugins/oh-my-codex/skills/team/SKILL.md +13 -9
  757. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +3 -2
  758. package/skills/autopilot/SKILL.md +13 -5
  759. package/skills/cancel/SKILL.md +30 -85
  760. package/skills/ralph/SKILL.md +6 -4
  761. package/skills/ralplan/SKILL.md +16 -17
  762. package/skills/team/SKILL.md +13 -9
  763. package/skills/ultragoal/SKILL.md +3 -2
  764. package/src/scripts/__tests__/codex-native-hook.test.ts +8831 -951
  765. package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +187 -0
  766. package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
  767. package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +187 -0
  768. package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +591 -0
  769. package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +701 -0
  770. package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +211 -0
  771. package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
  772. package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
  773. package/src/scripts/__tests__/postinstall.test.ts +23 -1
  774. package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +129 -0
  775. package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +67 -185
  776. package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +79 -178
  777. package/src/scripts/__tests__/smoke-packed-install.test.ts +525 -16
  778. package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
  779. package/src/scripts/codex-native-hook.ts +14238 -1429
  780. package/src/scripts/codex-native-pre-post.ts +43 -12
  781. package/src/scripts/generate-native-release-manifest.ts +83 -79
  782. package/src/scripts/notify-fallback-watcher.ts +91 -122
  783. package/src/scripts/notify-hook/auto-nudge.ts +71 -3
  784. package/src/scripts/notify-hook/state-io.ts +11 -0
  785. package/src/scripts/notify-hook/team-dispatch.ts +242 -75
  786. package/src/scripts/notify-hook/team-leader-nudge.ts +72 -22
  787. package/src/scripts/notify-hook/team-tmux-guard.ts +366 -39
  788. package/src/scripts/notify-hook/team-worker-stop.ts +43 -20
  789. package/src/scripts/notify-hook/team-worker.ts +82 -31
  790. package/src/scripts/notify-hook/tmux-injection.ts +33 -3
  791. package/src/scripts/notify-hook.ts +84 -82
  792. package/src/scripts/postinstall-advisory.ts +67 -0
  793. package/src/scripts/postinstall.ts +1 -1
  794. package/src/scripts/smoke-packed-install.ts +3608 -39
  795. package/src/scripts/sync-plugin-mirror.ts +17 -1
  796. package/src/scripts/verify-native-release-assets.ts +39 -31
  797. package/templates/AGENTS.md +1 -0
  798. package/dist/subagents/__tests__/adapted-role-binding.test.d.ts +0 -2
  799. package/dist/subagents/__tests__/adapted-role-binding.test.d.ts.map +0 -1
  800. package/dist/subagents/__tests__/adapted-role-binding.test.js +0 -988
  801. package/dist/subagents/__tests__/adapted-role-binding.test.js.map +0 -1
  802. package/dist/subagents/adapted-role-binding.d.ts +0 -17
  803. package/dist/subagents/adapted-role-binding.d.ts.map +0 -1
  804. package/dist/subagents/adapted-role-binding.js +0 -75
  805. package/dist/subagents/adapted-role-binding.js.map +0 -1
@@ -16,7 +16,7 @@ import TOML from "@iarna/toml";
16
16
  import { DEFAULT_FRONTIER_MODEL } from "./models.js";
17
17
  import { DEFAULT_CODEX_HOOK_FEATURE_FLAG, CODEX_HOOK_FEATURE_FLAGS, CODEX_PLUGIN_SCOPED_HOOKS_FEATURE_FLAG, formatCodexHookFeatureFlagLine, normalizeCodexHookFeatureFlag, } from "./codex-feature-flags.js";
18
18
  import { OMX_FIRST_PARTY_MCP_SERVER_NAMES, getOmxFirstPartySetupMcpServers, } from "./omx-first-party-mcp.js";
19
- import { buildManagedCodexHookTrustState, escapeTomlBasicString, ManagedCodexHooksPlanError, scanManagedCodexHookTrustStateFromContent, } from "./codex-hooks.js";
19
+ import { buildManagedCodexHookTrustState, escapeTomlBasicString, ManagedCodexHooksPlanError, } from "./codex-hooks.js";
20
20
  function escapeTomlString(value) {
21
21
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
22
22
  }
@@ -37,8 +37,8 @@ const LEGACY_SEEDED_MODEL_CONTEXT_WINDOW = 250000;
37
37
  const LEGACY_SEEDED_MODEL_AUTO_COMPACT_TOKEN_LIMIT = 200000;
38
38
  const OMX_SEEDED_BEHAVIORAL_DEFAULTS_START_MARKER = "# oh-my-codex seeded behavioral defaults (uninstall removes unchanged defaults)";
39
39
  const OMX_SEEDED_BEHAVIORAL_DEFAULTS_END_MARKER = "# End oh-my-codex seeded behavioral defaults";
40
- export const OMX_DEVELOPER_INSTRUCTIONS = "You have oh-my-codex installed. AGENTS.md is the orchestration brain and main control surface. Follow AGENTS.md for skill/keyword routing, $name workflow invocation, and role-specialized subagents; when the native surface exposes `agent_type` role routing, set `agent_type` to an installed role and never omit it for OMX work. When it does not (`role_routing_unavailable`, for example a Codex App `spawn_agent` surface exposing only `task_name`, `message`, and `fork_turns`), do not fabricate `agent_type`; follow the OMX adapted role-pass protocol by recording a pre-validated role intent in the OMX subagent ledger, and never fake the role via a prompt label. Use outcome-first, concise progress updates: state the target result, constraints, validation evidence, and stop condition before adding process detail. Native subagents live in .codex/agents and may handle independent parallel subtasks within one Codex session or team pane. Skills load from .codex/skills, not native-agent TOMLs. Treat installed prompts as narrower execution surfaces under AGENTS.md authority.";
41
- export const OMX_PLUGIN_DEVELOPER_INSTRUCTIONS = '<omx version="1">You have oh-my-codex installed through Codex plugin mode. AGENTS.md is the orchestration brain and main control surface. Follow AGENTS.md for skill/keyword routing and $name workflow invocation. When the native surface exposes `agent_type` role routing, set `agent_type` to an installed role and never omit it for OMX work. When it does not (`role_routing_unavailable`, for example a Codex App `spawn_agent` surface exposing only `task_name`, `message`, and `fork_turns`), do not fabricate `agent_type`; follow the OMX adapted role-pass protocol by recording a pre-validated role intent in the OMX subagent ledger, and never fake the role via a prompt label. Registered Codex plugin marketplace surfaces supply OMX workflows and plugin-scoped companion resources when the plugin is installed; native agent roles are installed as setup-owned Codex agent TOML files in plugin mode so agent_type routing works. User-installed skills may still live under ~/.codex/skills. Use outcome-first, concise progress updates: state the target result, constraints, validation evidence, and stop condition before adding process detail.</omx>';
40
+ export const OMX_DEVELOPER_INSTRUCTIONS = "You have oh-my-codex installed. AGENTS.md is the orchestration brain and main control surface. Follow AGENTS.md for skill/keyword routing, $name workflow invocation, and role-specialized subagents; when the native surface exposes `agent_type` role routing, set `agent_type` to an installed role and never omit it for OMX work. When it reports `role_routing_unavailable` and adapted Ralplan authority is requested, do not fabricate `agent_type`; run `omx ralplan preflight --json` and stop on `unsupported_documented_leader_proof`. Ordinary work remains under its own workflow gates. Never fake the role via a prompt label or infer authority from session/thread/pointer/transcript/cwd state. Use outcome-first, concise progress updates: state the target result, constraints, validation evidence, and stop condition before adding process detail. Native subagents live in .codex/agents and may handle independent parallel subtasks within one Codex session or team pane. Skills load from .codex/skills, not native-agent TOMLs. Treat installed prompts as narrower execution surfaces under AGENTS.md authority.";
41
+ export const OMX_PLUGIN_DEVELOPER_INSTRUCTIONS = '<omx version="1">You have oh-my-codex installed through Codex plugin mode. AGENTS.md is the orchestration brain and main control surface. Follow AGENTS.md for skill/keyword routing and $name workflow invocation. When the native surface exposes `agent_type` role routing, set `agent_type` to an installed role and never omit it for OMX work. When it reports `role_routing_unavailable` and adapted Ralplan authority is requested, do not fabricate `agent_type`; run `omx ralplan preflight --json` and stop on `unsupported_documented_leader_proof`. Ordinary work remains under its own workflow gates. Never fake the role via a prompt label or infer authority from session/thread/pointer/transcript/cwd state. Registered Codex plugin marketplace surfaces supply OMX workflows and plugin-scoped companion resources when the plugin is installed; native agent roles are installed as setup-owned Codex agent TOML files in plugin mode so agent_type routing works. User-installed skills may still live under ~/.codex/skills. Use outcome-first, concise progress updates: state the target result, constraints, validation evidence, and stop condition before adding process detail.</omx>';
42
42
  const SHARED_MCP_REGISTRY_MARKER = "oh-my-codex (OMX) Shared MCP Registry Sync";
43
43
  const SHARED_MCP_REGISTRY_END_MARKER = "# End oh-my-codex shared MCP registry sync";
44
44
  const LEGACY_MULTI_AGENT_KEYS = [
@@ -171,6 +171,40 @@ export async function cleanCodexModelAvailabilityNuxIfNeeded(configPath) {
171
171
  export function hasLegacyOmxTeamRunTable(config) {
172
172
  return LEGACY_OMX_TEAM_RUN_TABLE_PATTERN.test(config);
173
173
  }
174
+ function stripLegacyOmxTeamRunTable(config) {
175
+ const lines = config.split(/\r?\n/);
176
+ const result = [];
177
+ for (let i = 0; i < lines.length;) {
178
+ const line = lines[i];
179
+ if (!LEGACY_OMX_TEAM_RUN_TABLE_PATTERN.test(line)) {
180
+ result.push(line);
181
+ i += 1;
182
+ continue;
183
+ }
184
+ // Retired table found: drop any immediately preceding OMX comment or
185
+ // blank lines (mirrors stripOrphanedOmxSections), then the table header
186
+ // and its body up to the next [table] header.
187
+ while (result.length > 0) {
188
+ const last = result[result.length - 1];
189
+ if (last.trim() === "" || /^#\s*(OMX|oh-my-codex)/i.test(last)) {
190
+ result.pop();
191
+ }
192
+ else {
193
+ break;
194
+ }
195
+ }
196
+ i += 1;
197
+ // Consume the table body up to the next [table] header, but never past
198
+ // the OMX block footer — the end marker is a comment, not a header, and
199
+ // must survive a last-table removal (issue #3447).
200
+ while (i < lines.length && !/^\s*\[/.test(lines[i])) {
201
+ if (lines[i].trim() === OMX_CONFIG_END_MARKER)
202
+ break;
203
+ i += 1;
204
+ }
205
+ }
206
+ return result.join("\n");
207
+ }
174
208
  function unwrapTomlString(value) {
175
209
  return value?.match(/^"(.*)"$/)?.[1];
176
210
  }
@@ -653,45 +687,8 @@ const OMX_HOOK_TRUST_START_MARKER = "# OMX-owned Codex hook trust state";
653
687
  const OMX_HOOK_TRUST_END_MARKER = "# End OMX-owned Codex hook trust state";
654
688
  const OMX_PROJECT_TRUST_START_MARKER = "# OMX-synced Codex project trust state (from runtime CODEX_HOME)";
655
689
  const OMX_PROJECT_TRUST_END_MARKER = "# End OMX-synced Codex project trust state";
656
- function extractMarkerBlockContent(config, startMarker, endMarker) {
657
- const lines = config.split(/\r?\n/);
658
- for (let i = 0; i < lines.length; i++) {
659
- if (lines[i].trim() !== startMarker)
660
- continue;
661
- const nextEndIdx = lines.findIndex((line, index) => index > i && line.trim() === endMarker);
662
- const nextStartIdx = lines.findIndex((line, index) => index > i && line.trim() === startMarker);
663
- if (nextEndIdx === -1 || (nextStartIdx !== -1 && nextStartIdx < nextEndIdx)) {
664
- return undefined;
665
- }
666
- return lines.slice(i + 1, nextEndIdx).join("\n").trim();
667
- }
668
- return undefined;
669
- }
670
- function stripMarkerBlock(config, startMarker, endMarker) {
671
- const lines = config.split(/\r?\n/);
672
- const kept = [];
673
- for (let i = 0; i < lines.length;) {
674
- if (lines[i].trim() !== startMarker) {
675
- kept.push(lines[i]);
676
- i += 1;
677
- continue;
678
- }
679
- const nextEndIdx = lines.findIndex((line, index) => index > i && line.trim() === endMarker);
680
- const nextStartIdx = lines.findIndex((line, index) => index > i && line.trim() === startMarker);
681
- if (nextEndIdx === -1 || (nextStartIdx !== -1 && nextStartIdx < nextEndIdx)) {
682
- kept.push(lines[i]);
683
- i += 1;
684
- continue;
685
- }
686
- i = nextEndIdx + 1;
687
- }
688
- return kept.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd();
689
- }
690
690
  function isPlainTomlRecord(value) {
691
- return (typeof value === "object" &&
692
- value !== null &&
693
- !Array.isArray(value) &&
694
- Object.getPrototypeOf(value) === Object.prototype);
691
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
695
692
  }
696
693
  function safeParseToml(content) {
697
694
  try {
@@ -702,97 +699,514 @@ function safeParseToml(content) {
702
699
  return undefined;
703
700
  }
704
701
  }
705
- function collectProjectHookTrustStateKeys(config) {
706
- const keys = new Set();
707
- const parsed = safeParseToml(config);
708
- const hooksTable = isPlainTomlRecord(parsed) ? parsed.hooks : undefined;
709
- const hooksState = isPlainTomlRecord(hooksTable) ? hooksTable.state : undefined;
710
- if (!isPlainTomlRecord(hooksState))
711
- return keys;
712
- for (const [key, entry] of Object.entries(hooksState)) {
713
- if (!isPlainTomlRecord(entry))
714
- continue;
715
- keys.add(key);
702
+ function projectHookTrustState(config) {
703
+ const hooks = safeParseToml(config)?.hooks;
704
+ const state = isPlainTomlRecord(hooks) ? hooks.state : undefined;
705
+ return isPlainTomlRecord(state) ? state : undefined;
706
+ }
707
+ function projectTrustSemanticView(config) {
708
+ const hasLeadingBom = config.startsWith("\uFEFF");
709
+ const source = hasLeadingBom ? config.slice(1) : config;
710
+ if (source.includes("\uFEFF"))
711
+ return undefined;
712
+ return { source, prefix: hasLeadingBom ? "\uFEFF" : "" };
713
+ }
714
+ function projectTrustMarkerRange(config) {
715
+ const lexical = analyzeTomlSource(config);
716
+ if (!lexical.isUnambiguous)
717
+ return undefined;
718
+ const lines = sourceLines(config);
719
+ const starts = lines.filter((line, index) => lexical.lineStartsOutsideMultiline[index] && line.content.trim() === OMX_PROJECT_TRUST_START_MARKER);
720
+ const ends = lines.filter((line, index) => lexical.lineStartsOutsideMultiline[index] && line.content.trim() === OMX_PROJECT_TRUST_END_MARKER);
721
+ if (starts.length === 0 && ends.length === 0)
722
+ return { start: config.length, end: config.length, payloadStart: config.length, payloadEnd: config.length };
723
+ if (starts.length !== 1 || ends.length !== 1 || starts[0].start >= ends[0].start)
724
+ return undefined;
725
+ const start = starts[0];
726
+ const end = ends[0];
727
+ return { start: start.start, end: end.end, payloadStart: start.end, payloadEnd: end.start };
728
+ }
729
+ function hasInlineProjectTrustMarkerComment(config) {
730
+ const lexical = analyzeTomlSource(config);
731
+ return sourceLines(config).some((line, index) => {
732
+ if (!lexical.lineStartsOutsideMultiline[index])
733
+ return false;
734
+ const trimmed = line.content.trim();
735
+ return (trimmed.startsWith(OMX_PROJECT_TRUST_START_MARKER) && trimmed !== OMX_PROJECT_TRUST_START_MARKER) ||
736
+ (trimmed.startsWith(OMX_PROJECT_TRUST_END_MARKER) && trimmed !== OMX_PROJECT_TRUST_END_MARKER);
737
+ });
738
+ }
739
+ function projectTrustHeaderPath(line) {
740
+ if (/^\s*\[\[/.test(line))
741
+ return undefined;
742
+ const header = parseTomlSourceTableHeader(line);
743
+ if (!header?.parsed)
744
+ return undefined;
745
+ const path = [];
746
+ let cursor = header.parsed;
747
+ while (isPlainTomlRecord(cursor)) {
748
+ const keys = Object.keys(cursor);
749
+ if (keys.length === 0)
750
+ return path;
751
+ if (keys.length !== 1)
752
+ return undefined;
753
+ const key = keys[0];
754
+ path.push(key);
755
+ cursor = cursor[key];
716
756
  }
717
- return keys;
757
+ return path;
718
758
  }
719
- /**
720
- * Repairs project configs from the 0.18.3 relaunch regression where a
721
- * project-synced trust block could duplicate setup-owned hook trust tables and
722
- * make the next runtime CODEX_HOME config.toml invalid before Codex started.
723
- */
724
- export function repairProjectScopeTrustStateForLaunch(projectConfig, projectHooksPath) {
725
- const syncedTrustBlock = extractMarkerBlockContent(projectConfig, OMX_PROJECT_TRUST_START_MARKER, OMX_PROJECT_TRUST_END_MARKER);
726
- if (!syncedTrustBlock)
727
- return projectConfig;
728
- const stripped = stripMarkerBlock(projectConfig, OMX_PROJECT_TRUST_START_MARKER, OMX_PROJECT_TRUST_END_MARKER);
729
- const repaired = syncProjectScopeTrustStateFromRuntime(stripped, syncedTrustBlock, projectHooksPath);
730
- return repaired === stripped ? projectConfig : repaired;
759
+ function dominantProjectTrustEol(source) {
760
+ const crlfCount = (source.match(/\r\n/g) ?? []).length;
761
+ const lfCount = (source.match(/(?<!\r)\n/g) ?? []).length;
762
+ return crlfCount > lfCount ? "\r\n" : "\n";
763
+ }
764
+ function projectTrustPayloadIsSemanticallyEmpty(payload) {
765
+ const parsed = safeParseToml(payload);
766
+ return parsed !== undefined && Object.keys(parsed).length === 0;
767
+ }
768
+ function projectTrustValueAtPath(source, path) {
769
+ let value = source;
770
+ for (const key of path) {
771
+ if (!isPlainTomlRecord(value))
772
+ return undefined;
773
+ value = value[key];
774
+ }
775
+ return value;
731
776
  }
732
777
  /**
733
- * Project-scope launches mirror the durable project config.toml into an
734
- * ephemeral runtime CODEX_HOME. Codex writes its workspace-trust ledger and
735
- * hook trust ledger into the runtime config.toml during the session. Without
736
- * persistence, those entries die with the runtime, so Codex prompts to trust
737
- * the workspace and hooks on every launch (issue #2470).
738
- *
739
- * This function extracts only trust-state tables (`[projects."<cwd>"]` and
740
- * `[hooks.state."<projectHooksPath>:..."]`) from the runtime config.toml and
741
- * upserts them into the durable project config.toml inside a marker-fenced
742
- * block, preserving any surrounding user-managed content and comments and
743
- * ignoring Codex's NUX counters or other ephemeral runtime-only writes.
778
+ * Marker contents are an ownership boundary, not general TOML. Reject every
779
+ * source form that OMX did not emit rather than rebuilding it and losing data.
744
780
  */
745
- export function syncProjectScopeTrustStateFromRuntime(projectConfig, runtimeConfig, projectHooksPath) {
746
- const parsed = safeParseToml(runtimeConfig);
747
- if (!parsed)
748
- return projectConfig;
749
- const stripped = stripMarkerBlock(projectConfig, OMX_PROJECT_TRUST_START_MARKER, OMX_PROJECT_TRUST_END_MARKER);
750
- const existingHookTrustStateKeys = collectProjectHookTrustStateKeys(stripped);
751
- const trustBlockLines = [];
752
- const projectsTable = parsed.projects;
753
- if (isPlainTomlRecord(projectsTable)) {
754
- for (const [projectKey, entry] of Object.entries(projectsTable).sort(([a], [b]) => a.localeCompare(b))) {
755
- if (!isPlainTomlRecord(entry))
756
- continue;
757
- const serialized = TOML.stringify({ [projectKey]: entry });
758
- const renderedHeader = `[projects."${escapeTomlBasicString(projectKey)}"]`;
759
- const body = serialized
760
- .split(/\r?\n/)
761
- .filter((line) => !/^\s*\[/.test(line) && line.trim() !== "")
762
- .join("\n");
763
- if (body.length === 0)
764
- continue;
765
- trustBlockLines.push(renderedHeader, body, "");
781
+ function inventoryProjectTrustPayload(payload, projectHooksPath) {
782
+ const parsed = safeParseToml(payload);
783
+ const lexical = analyzeTomlSource(payload);
784
+ const headers = projectTrustHeaders(payload, { start: 0, end: payload.length });
785
+ if (!parsed || !lexical.isUnambiguous || !headers)
786
+ return undefined;
787
+ if (Object.keys(parsed).some((key) => key !== "projects" && key !== "hooks"))
788
+ return undefined;
789
+ const lines = sourceLines(payload);
790
+ const headerStarts = new Set(headers.map((header) => header.start));
791
+ for (const [index, line] of lines.entries()) {
792
+ if (!lexical.lineStartsOutsideMultiline[index])
793
+ return undefined;
794
+ const isHeader = headerStarts.has(line.start);
795
+ const isBlankOrComment = line.content.trim() === "" || /^\s*#/.test(line.content);
796
+ if (isHeader || isBlankOrComment) {
797
+ if (isHeader && lexical.lineHasTomlComment[index])
798
+ return undefined;
799
+ continue;
766
800
  }
801
+ if (lexical.lineHasTomlComment[index])
802
+ return undefined;
803
+ const priorHeader = headers.some((header) => header.start < line.start);
804
+ if (!priorHeader)
805
+ return undefined;
767
806
  }
768
- const hooksTable = parsed.hooks;
769
- const hooksState = isPlainTomlRecord(hooksTable) ? hooksTable.state : undefined;
770
- if (isPlainTomlRecord(hooksState)) {
771
- for (const [stateKey, entry] of Object.entries(hooksState).sort(([a], [b]) => a.localeCompare(b))) {
772
- if (!isPlainTomlRecord(entry))
773
- continue;
774
- if (!stateKey.startsWith(`${projectHooksPath}:`))
775
- continue;
776
- if (existingHookTrustStateKeys.has(stateKey))
807
+ const managedHeaders = [];
808
+ for (const header of headers) {
809
+ if (header.path[0] === "projects" && header.path.length >= 2) {
810
+ if (!isPlainTomlRecord(projectTrustValueAtPath(parsed, header.path)))
811
+ return undefined;
812
+ managedHeaders.push({ ...header, kind: "project" });
813
+ continue;
814
+ }
815
+ if (header.path[0] === "hooks" &&
816
+ header.path[1] === "state" &&
817
+ header.path.length === 3 &&
818
+ header.path[2].startsWith(`${projectHooksPath}:`)) {
819
+ const value = projectTrustValueAtPath(parsed, header.path);
820
+ if (!isPlainTomlRecord(value) || typeof value.trusted_hash !== "string" || value.trusted_hash.length === 0 || Object.keys(value).some((key) => key !== "trusted_hash"))
821
+ return undefined;
822
+ managedHeaders.push({ ...header, kind: "hook" });
823
+ continue;
824
+ }
825
+ return undefined;
826
+ }
827
+ if (!projectTrustPayloadProjectFamiliesAreValid(managedHeaders))
828
+ return undefined;
829
+ if (!projectTrustPayloadNestedStructuresAreExplicit(parsed, managedHeaders))
830
+ return undefined;
831
+ return { parsed, headers: managedHeaders };
832
+ }
833
+ function projectTrustSourceNestedStructuresAreExplicit(parsed, headers) {
834
+ const projects = parsed.projects;
835
+ if (projects === undefined)
836
+ return true;
837
+ if (!isPlainTomlRecord(projects))
838
+ return false;
839
+ const hasHeader = (path) => headers.some((header) => projectTrustEqual(header.path, path));
840
+ const visit = (value, path) => {
841
+ for (const [key, child] of Object.entries(value)) {
842
+ if (!isPlainTomlRecord(child))
777
843
  continue;
778
- const trusted = entry.trusted_hash;
779
- if (typeof trusted !== "string" || trusted.length === 0)
844
+ const childPath = [...path, key];
845
+ if (!hasHeader(childPath) || !visit(child, childPath))
846
+ return false;
847
+ }
848
+ return true;
849
+ };
850
+ return Object.entries(projects).every(([key, value]) => isPlainTomlRecord(value) && hasHeader(["projects", key]) && visit(value, ["projects", key]));
851
+ }
852
+ function projectTrustPayloadNestedStructuresAreExplicit(parsed, headers) {
853
+ const hasHeader = (path) => headers.some((header) => header.kind === "project" && projectTrustEqual(header.path, path));
854
+ const visit = (value, path) => {
855
+ for (const [key, child] of Object.entries(value)) {
856
+ if (!isPlainTomlRecord(child))
780
857
  continue;
781
- trustBlockLines.push(`[hooks.state."${escapeTomlBasicString(stateKey)}"]`, `trusted_hash = "${escapeTomlBasicString(trusted)}"`, "");
858
+ const childPath = [...path, key];
859
+ if (!hasHeader(childPath) || !visit(child, childPath))
860
+ return false;
782
861
  }
862
+ return true;
863
+ };
864
+ return headers
865
+ .filter((header) => header.kind === "project" && header.path.length === 2)
866
+ .every((header) => {
867
+ const value = projectTrustValueAtPath(parsed, header.path);
868
+ return isPlainTomlRecord(value) && visit(value, header.path);
869
+ });
870
+ }
871
+ function projectTrustPayloadTableSpan(source) {
872
+ const lines = sourceLines(source);
873
+ const lastBodyLine = lines
874
+ .slice(1)
875
+ .reverse()
876
+ .find((line) => line.content.trim() !== "" && !/^\s*#/.test(line.content));
877
+ if (!lastBodyLine)
878
+ return { source, gap: "" };
879
+ const bodyEnd = lastBodyLine.end;
880
+ return { source: source.slice(0, bodyEnd), gap: source.slice(bodyEnd) };
881
+ }
882
+ function projectTrustPayloadTableBodyHasCommentsOrBlanks(source) {
883
+ return sourceLines(source).some((line) => line.content.trim() === "" || /^\s*#/.test(line.content));
884
+ }
885
+ function reconcileProjectTrustPayload(payload, payloadInventory, externalProjects, runtimeProjects, runtimeHooksState, externalHookTrustState, projectHooksPath, eol) {
886
+ const { headers } = payloadInventory;
887
+ const payloadProjectKeys = new Set(headers.filter((header) => header.kind === "project").map((header) => header.path[1]));
888
+ const replacementByHeader = new Map();
889
+ for (const key of payloadProjectKeys) {
890
+ const projectHeaders = headers.filter((header) => header.kind === "project" && header.path[1] === key);
891
+ const parent = projectHeaders.find((header) => header.path.length === 2);
892
+ const payloadValue = projectTrustValueAtPath(payloadInventory.parsed, ["projects", key]);
893
+ const externalValue = externalProjects[key];
894
+ const runtimeValue = runtimeProjects[key];
895
+ if (externalValue !== undefined) {
896
+ if (!projectTrustEqual(payloadValue, externalValue) || (runtimeValue !== undefined && !projectTrustEqual(runtimeValue, externalValue)))
897
+ return undefined;
898
+ for (const header of projectHeaders)
899
+ replacementByHeader.set(header.start, undefined);
900
+ continue;
901
+ }
902
+ if (runtimeValue === undefined) {
903
+ for (const header of projectHeaders)
904
+ replacementByHeader.set(header.start, undefined);
905
+ continue;
906
+ }
907
+ if (!parent || projectHeaders.length !== 1 || !isPlainTomlRecord(runtimeValue))
908
+ return undefined;
909
+ const rendered = renderProjectTrust(key, runtimeValue);
910
+ if (!rendered)
911
+ return undefined;
912
+ replacementByHeader.set(parent.start, rendered.replaceAll("\n", eol));
913
+ }
914
+ for (const header of headers.filter((candidate) => candidate.kind === "hook")) {
915
+ const key = header.path[2];
916
+ const payloadValue = projectTrustValueAtPath(payloadInventory.parsed, header.path);
917
+ const runtimeValue = runtimeHooksState?.[key];
918
+ const externalValue = externalHookTrustState?.[key];
919
+ if (externalValue !== undefined) {
920
+ if (!projectTrustEqual(payloadValue, externalValue))
921
+ return undefined;
922
+ replacementByHeader.set(header.start, undefined);
923
+ continue;
924
+ }
925
+ if (!isPlainTomlRecord(runtimeValue) || typeof runtimeValue.trusted_hash !== "string" || runtimeValue.trusted_hash.length === 0) {
926
+ replacementByHeader.set(header.start, undefined);
927
+ continue;
928
+ }
929
+ replacementByHeader.set(header.start, `[hooks.state."${escapeTomlBasicString(key)}"]${eol}trusted_hash = "${escapeTomlBasicString(runtimeValue.trusted_hash)}"`);
930
+ }
931
+ const leadingGap = payload.slice(0, headers[0]?.start ?? payload.length);
932
+ const parts = headers.length === 0 ? [] : [leadingGap];
933
+ let trailingGap = headers.length === 0 ? leadingGap : "";
934
+ const appendPart = (part) => {
935
+ if (!part)
936
+ return;
937
+ const previous = parts.at(-1);
938
+ if (previous && !/(?:\r\n|\n)$/.test(previous) && !/^(?:\r\n|\n)/.test(part))
939
+ parts.push(eol);
940
+ parts.push(part);
941
+ };
942
+ for (const [index, header] of headers.entries()) {
943
+ const next = headers[index + 1];
944
+ const segmentEnd = next?.start ?? payload.length;
945
+ const replacement = replacementByHeader.get(header.start);
946
+ const span = projectTrustPayloadTableSpan(payload.slice(header.start, segmentEnd));
947
+ const tableBody = span.source.slice(header.end - header.start);
948
+ if (replacement !== undefined &&
949
+ replacement !== span.source &&
950
+ projectTrustPayloadTableBodyHasCommentsOrBlanks(tableBody)) {
951
+ return undefined;
952
+ }
953
+ if (!next) {
954
+ trailingGap = span.gap;
955
+ if (replacement !== undefined)
956
+ appendPart(replacement);
957
+ continue;
958
+ }
959
+ if (replacement !== undefined)
960
+ appendPart(replacement);
961
+ if (span.gap)
962
+ appendPart(span.gap);
783
963
  }
784
- if (trustBlockLines.length === 0) {
785
- return stripped.length === 0 ? "" : `${stripped}\n`;
964
+ const additions = [];
965
+ for (const [key, value] of Object.entries(runtimeProjects).sort(([left], [right]) => left.localeCompare(right))) {
966
+ if (externalProjects[key] !== undefined || payloadProjectKeys.has(key))
967
+ continue;
968
+ if (!isPlainTomlRecord(value))
969
+ return undefined;
970
+ const rendered = renderProjectTrust(key, value);
971
+ if (!rendered)
972
+ return undefined;
973
+ additions.push(`${rendered.replaceAll("\n", eol)}${eol}`);
786
974
  }
787
- const block = [
788
- OMX_PROJECT_TRUST_START_MARKER,
789
- ...trustBlockLines,
790
- OMX_PROJECT_TRUST_END_MARKER,
791
- "",
792
- ].join("\n");
793
- if (stripped.length === 0)
794
- return block;
795
- return `${stripped}\n\n${block}`;
975
+ for (const [key, value] of Object.entries(runtimeHooksState ?? {}).sort(([left], [right]) => left.localeCompare(right))) {
976
+ if (!key.startsWith(`${projectHooksPath}:`) || externalHookTrustState?.[key] !== undefined || headers.some((header) => header.kind === "hook" && header.path[2] === key))
977
+ continue;
978
+ if (!isPlainTomlRecord(value) || typeof value.trusted_hash !== "string" || value.trusted_hash.length === 0)
979
+ continue;
980
+ additions.push(`[hooks.state."${escapeTomlBasicString(key)}"]${eol}trusted_hash = "${escapeTomlBasicString(value.trusted_hash)}"${eol}`);
981
+ }
982
+ let reconciled = parts.join("");
983
+ if (additions.length > 0 && reconciled && !/(?:\r\n|\n)$/.test(reconciled))
984
+ reconciled += eol;
985
+ reconciled += additions.join("");
986
+ if (trailingGap && reconciled && !/(?:\r\n|\n)$/.test(reconciled) && !/^(?:\r\n|\n)/.test(trailingGap))
987
+ reconciled += eol;
988
+ reconciled += trailingGap;
989
+ reconciled = reconciled.replace(/(?:\r\n|\n)$/, "");
990
+ return Object.keys(safeParseToml(reconciled) ?? {}).length === 0 ? "" : reconciled;
991
+ }
992
+ function projectTrustHeaders(config, region) {
993
+ const lexical = analyzeTomlSource(config);
994
+ if (!lexical.isUnambiguous)
995
+ return undefined;
996
+ const lines = sourceLines(config);
997
+ const headers = [];
998
+ for (const [index, line] of lines.entries()) {
999
+ if (line.start < region.start || line.start >= region.end || !lexical.lineStartsOutsideMultiline[index])
1000
+ continue;
1001
+ if (!/^\s*\[/.test(line.content))
1002
+ continue;
1003
+ const path = projectTrustHeaderPath(line.content);
1004
+ if (!path) {
1005
+ if (/^\s*\[\[?\s*(?:projects|"projects"|'projects')/.test(line.content))
1006
+ return undefined;
1007
+ continue;
1008
+ }
1009
+ headers.push({ start: line.start, end: line.end, path });
1010
+ }
1011
+ return headers;
1012
+ }
1013
+ function inventoryProjectTrustSource(config) {
1014
+ const parsed = safeParseToml(config);
1015
+ if (!parsed)
1016
+ return undefined;
1017
+ const projects = parsed.projects;
1018
+ if (projects !== undefined && !isPlainTomlRecord(projects))
1019
+ return undefined;
1020
+ const headers = projectTrustHeaders(config, { start: 0, end: config.length });
1021
+ if (!headers)
1022
+ return undefined;
1023
+ const projectHeaders = headers.filter((header) => header.path[0] === "projects");
1024
+ if (projectHeaders.some((header) => header.path.length < 2))
1025
+ return undefined;
1026
+ for (const key of Object.keys(projects ?? {})) {
1027
+ if (projectHeaders.filter((header) => header.path.length === 2 && header.path[1] === key).length !== 1) {
1028
+ return undefined;
1029
+ }
1030
+ }
1031
+ if (!projectTrustSourceNestedStructuresAreExplicit(parsed, projectHeaders))
1032
+ return undefined;
1033
+ return { projects: projects ?? {}, headers };
1034
+ }
1035
+ function projectTrustCandidateIsSafe(candidate, external, runtimeProjects) {
1036
+ const marker = projectTrustMarkerRange(candidate);
1037
+ const inventory = inventoryProjectTrustSource(candidate);
1038
+ const externalInventory = inventoryProjectTrustSource(external);
1039
+ if (!inventory || !externalInventory)
1040
+ return false;
1041
+ const hasMarker = marker !== undefined && marker.start !== marker.end;
1042
+ const hasEquivalentExternalBytes = (actual) => {
1043
+ if (actual === external)
1044
+ return true;
1045
+ return splitProjectTrustTrailingEols(actual).body === splitProjectTrustTrailingEols(external).body;
1046
+ };
1047
+ if (hasMarker) {
1048
+ const candidateExternal = `${candidate.slice(0, marker.start)}${candidate.slice(marker.end)}`;
1049
+ if (!hasEquivalentExternalBytes(candidateExternal) && !(candidate.startsWith(external) && candidate.slice(marker.end).length === 0 && /^(?:\r\n|\n)+$/.test(candidate.slice(external.length, marker.start))))
1050
+ return false;
1051
+ }
1052
+ else if (!hasEquivalentExternalBytes(candidate)) {
1053
+ return false;
1054
+ }
1055
+ const expectedProjects = { ...externalInventory.projects, ...runtimeProjects };
1056
+ if (!projectTrustEqual(inventory.projects, expectedProjects))
1057
+ return false;
1058
+ for (const [key, value] of Object.entries(expectedProjects)) {
1059
+ if (!projectTrustEqual(inventory.projects[key], value))
1060
+ return false;
1061
+ if (inventory.headers.filter((header) => header.path[0] === "projects" && header.path.length === 2 && header.path[1] === key).length !== 1)
1062
+ return false;
1063
+ }
1064
+ return true;
1065
+ }
1066
+ function projectTrustPayloadProjectFamiliesAreValid(headers) {
1067
+ const projectKeys = new Set(headers.filter((header) => header.kind === "project").map((header) => header.path[1]));
1068
+ for (const key of projectKeys) {
1069
+ const family = headers.filter((header) => header.kind === "project" && header.path[1] === key);
1070
+ const parents = family.filter((header) => header.path.length === 2);
1071
+ if (parents.length !== 1 || !projectTrustFamilyIsContiguous(headers, parents[0]))
1072
+ return false;
1073
+ }
1074
+ return true;
1075
+ }
1076
+ function projectTrustFamilyIsContiguous(headers, parent) {
1077
+ const first = headers.indexOf(parent);
1078
+ let ended = false;
1079
+ for (let index = first + 1; index < headers.length; index += 1) {
1080
+ const path = headers[index].path;
1081
+ const belongsToFamily = path[0] === "projects" && path[1] === parent.path[1];
1082
+ if (!belongsToFamily) {
1083
+ ended = true;
1084
+ continue;
1085
+ }
1086
+ if (ended || path.length < 3)
1087
+ return false;
1088
+ }
1089
+ return true;
1090
+ }
1091
+ function projectTrustEqual(left, right) {
1092
+ if (Object.is(left, right))
1093
+ return true;
1094
+ if (left instanceof Date || right instanceof Date) {
1095
+ return left instanceof Date && right instanceof Date && left.constructor === right.constructor && String(left) === String(right);
1096
+ }
1097
+ if (Array.isArray(left) || Array.isArray(right)) {
1098
+ return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => projectTrustEqual(value, right[index]));
1099
+ }
1100
+ if (!isPlainTomlRecord(left) || !isPlainTomlRecord(right))
1101
+ return false;
1102
+ const leftKeys = Object.keys(left).sort();
1103
+ const rightKeys = Object.keys(right).sort();
1104
+ return leftKeys.length === rightKeys.length && leftKeys.every((key, index) => key === rightKeys[index] && projectTrustEqual(left[key], right[key]));
1105
+ }
1106
+ function canRenderFlatProjectTrust(entry) {
1107
+ const isValue = (value) => {
1108
+ if (Array.isArray(value))
1109
+ return value.every(isValue);
1110
+ return !isPlainTomlRecord(value);
1111
+ };
1112
+ return Object.values(entry).every(isValue);
1113
+ }
1114
+ function renderProjectTrust(projectKey, entry) {
1115
+ if (!canRenderFlatProjectTrust(entry))
1116
+ return undefined;
1117
+ const serialized = TOML.stringify({ [projectKey]: entry });
1118
+ const body = serialized.split(/\r?\n/).filter((line) => !/^\s*\[/.test(line) && line.trim() !== "").join("\n");
1119
+ return body ? `[projects."${escapeTomlBasicString(projectKey)}"]\n${body}` : undefined;
1120
+ }
1121
+ function splitProjectTrustTrailingEols(source) {
1122
+ const match = source.match(/(?:(?:\r\n|\n))*$/);
1123
+ const trailingEols = match?.[0] ?? "";
1124
+ return { body: source.slice(0, source.length - trailingEols.length), trailingEols };
1125
+ }
1126
+ function appendProjectTrustMarker(base, payload, eol, trailingEols) {
1127
+ if (!payload)
1128
+ return `${splitProjectTrustTrailingEols(base).body}${trailingEols}`;
1129
+ const { body } = splitProjectTrustTrailingEols(base);
1130
+ const separator = body ? `${eol}${eol}` : "";
1131
+ const block = `${OMX_PROJECT_TRUST_START_MARKER}${eol}${payload}${eol}${OMX_PROJECT_TRUST_END_MARKER}`;
1132
+ return `${body}${separator}${block}${trailingEols}`;
1133
+ }
1134
+ function reconcileProjectScopeTrustState(projectConfig, runtimeConfig, projectHooksPath, requireExistingPayload) {
1135
+ const durable = projectTrustSemanticView(projectConfig);
1136
+ const runtime = projectTrustSemanticView(runtimeConfig);
1137
+ if (!durable || !runtime)
1138
+ return projectConfig;
1139
+ if (hasInlineProjectTrustMarkerComment(durable.source) || hasInlineProjectTrustMarkerComment(runtime.source))
1140
+ return projectConfig;
1141
+ const parsedRuntime = safeParseToml(runtime.source);
1142
+ const runtimeInventory = inventoryProjectTrustSource(runtime.source);
1143
+ if (!parsedRuntime || !runtimeInventory)
1144
+ return projectConfig;
1145
+ const marker = projectTrustMarkerRange(durable.source);
1146
+ if (!marker)
1147
+ return projectConfig;
1148
+ const hasMarker = marker.start !== marker.end;
1149
+ const payload = durable.source.slice(marker.payloadStart, marker.payloadEnd);
1150
+ const payloadIsEmpty = projectTrustPayloadIsSemanticallyEmpty(payload);
1151
+ const payloadInventory = hasMarker
1152
+ ? inventoryProjectTrustPayload(payload, projectHooksPath)
1153
+ : { parsed: {}, headers: [] };
1154
+ if (!payloadInventory)
1155
+ return projectConfig;
1156
+ if (requireExistingPayload && (!hasMarker || payloadIsEmpty))
1157
+ return projectConfig;
1158
+ const external = hasMarker
1159
+ ? `${durable.source.slice(0, marker.start)}${durable.source.slice(marker.end)}`
1160
+ : durable.source;
1161
+ const trailingEols = splitProjectTrustTrailingEols(durable.source).trailingEols;
1162
+ const externalInventory = inventoryProjectTrustSource(external);
1163
+ if (!externalInventory)
1164
+ return projectConfig;
1165
+ const projects = runtimeInventory.projects;
1166
+ const externalProjects = externalInventory.projects;
1167
+ const headersBeforeMarker = projectTrustHeaders(durable.source, { start: 0, end: marker.start });
1168
+ const headersAfterMarker = projectTrustHeaders(durable.source, { start: marker.end, end: durable.source.length });
1169
+ if (!headersBeforeMarker || !headersAfterMarker)
1170
+ return projectConfig;
1171
+ const headers = [...headersBeforeMarker, ...headersAfterMarker];
1172
+ for (const key of Object.keys(externalProjects)) {
1173
+ const family = headers.filter((header) => header.path[0] === "projects" && header.path[1] === key);
1174
+ const parents = family.filter((header) => header.path.length === 2);
1175
+ if (parents.length !== 1)
1176
+ return projectConfig;
1177
+ const parentIsBeforeMarker = parents[0].start < marker.start;
1178
+ if (family.some((header) => (header.start < marker.start) !== parentIsBeforeMarker))
1179
+ return projectConfig;
1180
+ if (!projectTrustFamilyIsContiguous(headers, parents[0]))
1181
+ return projectConfig;
1182
+ }
1183
+ const eol = dominantProjectTrustEol(durable.source);
1184
+ const hooks = parsedRuntime.hooks;
1185
+ const hooksState = isPlainTomlRecord(hooks) && isPlainTomlRecord(hooks.state) ? hooks.state : undefined;
1186
+ const nextPayload = reconcileProjectTrustPayload(payload, payloadInventory, externalProjects, projects, hooksState, projectHookTrustState(external), projectHooksPath, eol);
1187
+ if (nextPayload === undefined)
1188
+ return projectConfig;
1189
+ if (!inventoryProjectTrustPayload(nextPayload, projectHooksPath))
1190
+ return projectConfig;
1191
+ const candidate = appendProjectTrustMarker(external, nextPayload, eol, trailingEols);
1192
+ if (!projectTrustCandidateIsSafe(candidate, external, projects))
1193
+ return projectConfig;
1194
+ return `${durable.prefix}${candidate}`;
1195
+ }
1196
+ /** Repairs only a uniquely parseable, nonempty project-sync payload before mirror creation. */
1197
+ export function repairProjectScopeTrustStateForLaunch(projectConfig, projectHooksPath) {
1198
+ const durable = projectTrustSemanticView(projectConfig);
1199
+ if (!durable)
1200
+ return projectConfig;
1201
+ const marker = projectTrustMarkerRange(durable.source);
1202
+ if (!marker || marker.start === marker.end)
1203
+ return projectConfig;
1204
+ const payload = durable.source.slice(marker.payloadStart, marker.payloadEnd);
1205
+ return reconcileProjectScopeTrustState(projectConfig, payload, projectHooksPath, true);
1206
+ }
1207
+ /** Conservatively persists runtime project and hook trust without rewriting external TOML. */
1208
+ export function syncProjectScopeTrustStateFromRuntime(projectConfig, runtimeConfig, projectHooksPath) {
1209
+ return reconcileProjectScopeTrustState(projectConfig, runtimeConfig, projectHooksPath, false);
796
1210
  }
797
1211
  function isMultilineTomlString(mode) {
798
1212
  return mode === "multiline-basic" || mode === "multiline-literal";
@@ -2243,6 +2657,49 @@ function upsertTuiStatusLine(config, preset = DEFAULT_STATUS_LINE_PRESET, option
2243
2657
  hadExistingTui: true,
2244
2658
  };
2245
2659
  }
2660
+ /**
2661
+ * Collapse duplicate `[tui]` tables to a single verbatim first table.
2662
+ *
2663
+ * The launch repair uses this instead of `upsertTuiStatusLine` so the first
2664
+ * table — including any surrounding OMX marker comments that precede the next
2665
+ * [table] header — is preserved byte-for-byte and no status line is injected.
2666
+ */
2667
+ function dedupeTuiTables(config) {
2668
+ const lines = config.split(/\r?\n/);
2669
+ const sections = [];
2670
+ for (let i = 0; i < lines.length; i += 1) {
2671
+ if (!/^\s*\[tui\]\s*$/.test(lines[i]))
2672
+ continue;
2673
+ let end = lines.length;
2674
+ for (let j = i + 1; j < lines.length; j += 1) {
2675
+ if (/^\s*\[\[?[^\]]+\]?\]\s*$/.test(lines[j])) {
2676
+ end = j;
2677
+ break;
2678
+ }
2679
+ // The OMX block footer is comments, not a [table] header — stop before
2680
+ // it so dropping a trailing duplicate never swallows the end marker.
2681
+ if (lines[j].trim() === OMX_CONFIG_END_MARKER) {
2682
+ end = j;
2683
+ break;
2684
+ }
2685
+ }
2686
+ sections.push({ start: i, end });
2687
+ i = end - 1;
2688
+ }
2689
+ if (sections.length <= 1)
2690
+ return config;
2691
+ const droppedStarts = new Set(sections.slice(1).map((section) => section.start));
2692
+ const rebuilt = [];
2693
+ for (let i = 0; i < lines.length; i += 1) {
2694
+ const dropped = sections.find((section) => section.start === i);
2695
+ if (dropped && droppedStarts.has(i)) {
2696
+ i = dropped.end - 1;
2697
+ continue;
2698
+ }
2699
+ rebuilt.push(lines[i]);
2700
+ }
2701
+ return rebuilt.join("\n").replace(/\n{3,}/g, "\n\n");
2702
+ }
2246
2703
  // ---------------------------------------------------------------------------
2247
2704
  // OMX [table] sections block (appended at end of file)
2248
2705
  // ---------------------------------------------------------------------------
@@ -2655,36 +3112,20 @@ export function buildMergedConfig(existingConfig, pkgRoot, options = {}) {
2655
3112
  * OMX builds no longer ship the team MCP entrypoint, so we repair both before
2656
3113
  * the CLI is spawned.
2657
3114
  *
3115
+ * The repair is surgical: only the detected targets are changed — missing
3116
+ * launcher-backed MCP `startup_timeout_sec` entries are added, retired
3117
+ * `[mcp_servers.omx_team_run]` tables are dropped, and duplicate `[tui]`
3118
+ * tables are deduplicated. Everything else is preserved byte-for-byte,
3119
+ * including user-owned `notify` and `model_reasoning_effort` values, managed
3120
+ * hook trust state, and any existing OMX managed block; a config that never
3121
+ * had an OMX block does not get one injected (see issue #3447).
3122
+ *
3123
+ * `pkgRoot` and `options` are retained for API compatibility; the surgical
3124
+ * repair does not rebuild the managed block, so it never needs them.
3125
+ *
2658
3126
  * Returns `true` if a repair was performed.
2659
3127
  */
2660
- function managedHookTrustProofRequiredForRepair(config) {
2661
- const inventory = collectManagedHookTrustStateSourceRepresentations(config);
2662
- return managedMarkerTrustStateConflicts(inventory.source, inventory.representations, inventory.managedMarkerRanges, inventory.markerContainedHooksStateSpans, inventory.invalidMarkerContainedHooksStateSpans, inventory.parsedStatementSpans, inventory.parsedAssignmentSpans, managedHookTrustStateExpectations()).size > 0;
2663
- }
2664
- async function launchRepairOptionsWithManagedHookTrustProof(configPath, config, options) {
2665
- if (!managedHookTrustProofRequiredForRepair(config)) {
2666
- return options;
2667
- }
2668
- const hooksPath = options.codexHooksFile ?? resolve(configPath, "..", "hooks.json");
2669
- let hooksContent;
2670
- try {
2671
- hooksContent = await readFile(hooksPath, "utf-8");
2672
- }
2673
- catch (error) {
2674
- throw new ManagedCodexHooksPlanError("invalid_document", `Cannot safely repair config.toml because the current hooks artifact at ${hooksPath} could not be read.`, { cause: String(error), hooksPath });
2675
- }
2676
- const trustScan = scanManagedCodexHookTrustStateFromContent(hooksContent, hooksPath, managedCodexHookOptionsFromMergeOptions(options));
2677
- if (!trustScan.ok)
2678
- throw trustScan.error;
2679
- return {
2680
- ...options,
2681
- codexHooksFile: hooksPath,
2682
- codexHooksContent: hooksContent,
2683
- managedHookTrustState: trustScan.trustState,
2684
- priorManagedHookTrustState: trustScan.trustState,
2685
- };
2686
- }
2687
- export async function repairConfigIfNeeded(configPath, pkgRoot, options = {}) {
3128
+ export async function repairConfigIfNeeded(configPath, _pkgRoot, _options = {}) {
2688
3129
  if (!existsSync(configPath))
2689
3130
  return false;
2690
3131
  const content = await readFile(configPath, "utf-8");
@@ -2693,15 +3134,32 @@ export async function repairConfigIfNeeded(configPath, pkgRoot, options = {}) {
2693
3134
  const hasLauncherTimeoutGap = findLauncherTimeoutRepairTargets(content).length > 0;
2694
3135
  if (tuiCount <= 1 && !hasLegacyTeamRunTable && !hasLauncherTimeoutGap)
2695
3136
  return false;
2696
- // Managed config compatibility issue detected — derive proof from the current
2697
- // hooks artifact before any marker stripping can replace managed trust state.
2698
- const repairOptions = await launchRepairOptionsWithManagedHookTrustProof(configPath, content, options);
2699
- const repaired = buildMergedConfig(content, pkgRoot, repairOptions);
3137
+ let repaired = content;
3138
+ if (hasLauncherTimeoutGap) {
3139
+ repaired = addDefaultLauncherMcpStartupTimeouts(repaired);
3140
+ }
3141
+ if (hasLegacyTeamRunTable) {
3142
+ repaired = stripLegacyOmxTeamRunTable(repaired);
3143
+ }
3144
+ if (tuiCount > 1) {
3145
+ repaired = dedupeTuiTables(repaired);
3146
+ }
2700
3147
  if (repaired === content)
2701
3148
  return false;
3149
+ // The surgical helpers normalize to LF internally; write back with the
3150
+ // original file's dominant line ending so a CRLF config stays CRLF.
3151
+ const newline = dominantNewline(content);
3152
+ if (newline === "\r\n") {
3153
+ repaired = repaired.replace(/\r?\n/g, "\r\n");
3154
+ }
2702
3155
  await writeFile(configPath, repaired);
2703
3156
  return true;
2704
3157
  }
3158
+ function dominantNewline(text) {
3159
+ const crlf = (text.match(/\r\n/g) ?? []).length;
3160
+ const lf = (text.match(/\n/g) ?? []).length - crlf;
3161
+ return crlf >= lf ? "\r\n" : "\n";
3162
+ }
2705
3163
  export async function mergeConfig(configPath, pkgRoot, options = {}) {
2706
3164
  let existing = "";
2707
3165
  if (existsSync(configPath)) {