oh-my-codex 0.11.12 → 0.11.13

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 (248) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +23 -0
  4. package/README.vi.md +144 -185
  5. package/crates/omx-runtime-core/src/engine.rs +122 -4
  6. package/crates/omx-runtime-core/src/lib.rs +17 -0
  7. package/dist/cli/__tests__/autoresearch.test.js +11 -0
  8. package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
  9. package/dist/cli/__tests__/cleanup.test.js +117 -4
  10. package/dist/cli/__tests__/cleanup.test.js.map +1 -1
  11. package/dist/cli/__tests__/error-handling-warnings.test.js +13 -0
  12. package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
  13. package/dist/cli/__tests__/exec.test.js +6 -0
  14. package/dist/cli/__tests__/exec.test.js.map +1 -1
  15. package/dist/cli/__tests__/index.test.js +94 -1
  16. package/dist/cli/__tests__/index.test.js.map +1 -1
  17. package/dist/cli/__tests__/launch-fallback.test.js +3 -0
  18. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  19. package/dist/cli/__tests__/package-bin-contract.test.js +10 -0
  20. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  21. package/dist/cli/__tests__/packaged-script-resolution.test.js +4 -3
  22. package/dist/cli/__tests__/packaged-script-resolution.test.js.map +1 -1
  23. package/dist/cli/__tests__/resume.test.js +6 -0
  24. package/dist/cli/__tests__/resume.test.js.map +1 -1
  25. package/dist/cli/__tests__/setup-refresh.test.js +29 -12
  26. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  27. package/dist/cli/__tests__/star-prompt.test.js +16 -0
  28. package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
  29. package/dist/cli/__tests__/uninstall.test.js +112 -1
  30. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  31. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +2 -0
  32. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +1 -0
  33. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +30 -0
  34. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -0
  35. package/dist/cli/cleanup.d.ts +2 -0
  36. package/dist/cli/cleanup.d.ts.map +1 -1
  37. package/dist/cli/cleanup.js +26 -1
  38. package/dist/cli/cleanup.js.map +1 -1
  39. package/dist/cli/index.d.ts +7 -0
  40. package/dist/cli/index.d.ts.map +1 -1
  41. package/dist/cli/index.js +161 -50
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/cli/setup.d.ts.map +1 -1
  44. package/dist/cli/setup.js +15 -14
  45. package/dist/cli/setup.js.map +1 -1
  46. package/dist/cli/star-prompt.d.ts.map +1 -1
  47. package/dist/cli/star-prompt.js +1 -0
  48. package/dist/cli/star-prompt.js.map +1 -1
  49. package/dist/cli/team.d.ts.map +1 -1
  50. package/dist/cli/team.js +5 -1
  51. package/dist/cli/team.js.map +1 -1
  52. package/dist/cli/uninstall.d.ts.map +1 -1
  53. package/dist/cli/uninstall.js +26 -0
  54. package/dist/cli/uninstall.js.map +1 -1
  55. package/dist/cli/update.d.ts.map +1 -1
  56. package/dist/cli/update.js +1 -0
  57. package/dist/cli/update.js.map +1 -1
  58. package/dist/config/__tests__/generator-idempotent.test.js +4 -4
  59. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  60. package/dist/config/__tests__/mcp-registry.test.js +13 -16
  61. package/dist/config/__tests__/mcp-registry.test.js.map +1 -1
  62. package/dist/config/mcp-registry.d.ts +1 -0
  63. package/dist/config/mcp-registry.d.ts.map +1 -1
  64. package/dist/config/mcp-registry.js +4 -4
  65. package/dist/config/mcp-registry.js.map +1 -1
  66. package/dist/config/models.d.ts +1 -0
  67. package/dist/config/models.d.ts.map +1 -1
  68. package/dist/config/models.js +39 -1
  69. package/dist/config/models.js.map +1 -1
  70. package/dist/hooks/__tests__/keyword-detector.test.js +12 -1
  71. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  72. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +499 -17
  73. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  74. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +140 -14
  75. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  76. package/dist/hooks/__tests__/notify-hook-modules.test.js +5 -0
  77. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
  78. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +2 -0
  79. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +1 -0
  80. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +597 -0
  81. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -0
  82. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +15 -1
  83. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +73 -53
  85. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  86. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +193 -2
  87. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  88. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +183 -0
  89. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  90. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +255 -97
  91. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  92. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
  93. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
  94. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +46 -0
  95. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  96. package/dist/hooks/keyword-detector.d.ts +1 -0
  97. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  98. package/dist/hooks/keyword-detector.js +48 -0
  99. package/dist/hooks/keyword-detector.js.map +1 -1
  100. package/dist/hooks/session.d.ts.map +1 -1
  101. package/dist/hooks/session.js +1 -0
  102. package/dist/hooks/session.js.map +1 -1
  103. package/dist/hud/__tests__/state.test.js +70 -1
  104. package/dist/hud/__tests__/state.test.js.map +1 -1
  105. package/dist/hud/state.d.ts.map +1 -1
  106. package/dist/hud/state.js +10 -37
  107. package/dist/hud/state.js.map +1 -1
  108. package/dist/mcp/state-server.d.ts.map +1 -1
  109. package/dist/mcp/state-server.js +5 -0
  110. package/dist/mcp/state-server.js.map +1 -1
  111. package/dist/modes/__tests__/base-session-scope.test.js +46 -0
  112. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  113. package/dist/modes/base.d.ts.map +1 -1
  114. package/dist/modes/base.js +4 -0
  115. package/dist/modes/base.js.map +1 -1
  116. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +2 -0
  117. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +1 -0
  118. package/dist/notifications/__tests__/custom-alias-enablement.test.js +84 -0
  119. package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +1 -0
  120. package/dist/notifications/__tests__/idle-cooldown.test.js +55 -0
  121. package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
  122. package/dist/notifications/idle-cooldown.d.ts +8 -6
  123. package/dist/notifications/idle-cooldown.d.ts.map +1 -1
  124. package/dist/notifications/idle-cooldown.js +53 -22
  125. package/dist/notifications/idle-cooldown.js.map +1 -1
  126. package/dist/notifications/notifier.js +1 -1
  127. package/dist/notifications/notifier.js.map +1 -1
  128. package/dist/notifications/reply-listener.d.ts.map +1 -1
  129. package/dist/notifications/reply-listener.js +1 -0
  130. package/dist/notifications/reply-listener.js.map +1 -1
  131. package/dist/openclaw/config.js +2 -2
  132. package/dist/openclaw/config.js.map +1 -1
  133. package/dist/runtime/bridge.d.ts +1 -0
  134. package/dist/runtime/bridge.d.ts.map +1 -1
  135. package/dist/runtime/bridge.js +2 -6
  136. package/dist/runtime/bridge.js.map +1 -1
  137. package/dist/scripts/notify-fallback-watcher.js +97 -59
  138. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  139. package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -1
  140. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  141. package/dist/scripts/notify-hook/auto-nudge.js +72 -238
  142. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  143. package/dist/scripts/notify-hook/managed-tmux.d.ts +19 -0
  144. package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -0
  145. package/dist/scripts/notify-hook/managed-tmux.js +320 -0
  146. package/dist/scripts/notify-hook/managed-tmux.js.map +1 -0
  147. package/dist/scripts/notify-hook/ralph-session-resume.d.ts +22 -0
  148. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -0
  149. package/dist/scripts/notify-hook/ralph-session-resume.js +277 -0
  150. package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -0
  151. package/dist/scripts/notify-hook/state-io.d.ts +1 -1
  152. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  153. package/dist/scripts/notify-hook/state-io.js +2 -10
  154. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  155. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  156. package/dist/scripts/notify-hook/team-dispatch.js +60 -59
  157. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  158. package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -1
  159. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  160. package/dist/scripts/notify-hook/team-leader-nudge.js +13 -5
  161. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  162. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  163. package/dist/scripts/notify-hook/team-tmux-guard.js +1 -19
  164. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  165. package/dist/scripts/notify-hook/team-worker.js +4 -4
  166. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  167. package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -1
  168. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  169. package/dist/scripts/notify-hook/tmux-injection.js +102 -35
  170. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  171. package/dist/scripts/notify-hook.js +144 -20
  172. package/dist/scripts/notify-hook.js.map +1 -1
  173. package/dist/scripts/tmux-hook-engine.d.ts +1 -0
  174. package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
  175. package/dist/scripts/tmux-hook-engine.js +3 -0
  176. package/dist/scripts/tmux-hook-engine.js.map +1 -1
  177. package/dist/team/__tests__/api-interop.test.js +96 -4
  178. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  179. package/dist/team/__tests__/leader-activity.test.js +107 -2
  180. package/dist/team/__tests__/leader-activity.test.js.map +1 -1
  181. package/dist/team/__tests__/runtime-cli.test.js +32 -0
  182. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  183. package/dist/team/__tests__/runtime.test.js +148 -0
  184. package/dist/team/__tests__/runtime.test.js.map +1 -1
  185. package/dist/team/__tests__/shutdown-fallback.test.js +13 -0
  186. package/dist/team/__tests__/shutdown-fallback.test.js.map +1 -1
  187. package/dist/team/__tests__/state-root.test.js +11 -1
  188. package/dist/team/__tests__/state-root.test.js.map +1 -1
  189. package/dist/team/__tests__/state.test.js +16 -5
  190. package/dist/team/__tests__/state.test.js.map +1 -1
  191. package/dist/team/__tests__/tmux-session.test.js +460 -2
  192. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  193. package/dist/team/api-interop.d.ts.map +1 -1
  194. package/dist/team/api-interop.js +34 -7
  195. package/dist/team/api-interop.js.map +1 -1
  196. package/dist/team/commit-hygiene.d.ts +60 -0
  197. package/dist/team/commit-hygiene.d.ts.map +1 -0
  198. package/dist/team/commit-hygiene.js +232 -0
  199. package/dist/team/commit-hygiene.js.map +1 -0
  200. package/dist/team/leader-activity.d.ts.map +1 -1
  201. package/dist/team/leader-activity.js +17 -35
  202. package/dist/team/leader-activity.js.map +1 -1
  203. package/dist/team/runtime-cli.d.ts +9 -1
  204. package/dist/team/runtime-cli.d.ts.map +1 -1
  205. package/dist/team/runtime-cli.js +15 -6
  206. package/dist/team/runtime-cli.js.map +1 -1
  207. package/dist/team/runtime.d.ts +7 -2
  208. package/dist/team/runtime.d.ts.map +1 -1
  209. package/dist/team/runtime.js +391 -63
  210. package/dist/team/runtime.js.map +1 -1
  211. package/dist/team/state/dispatch.js +1 -1
  212. package/dist/team/state/dispatch.js.map +1 -1
  213. package/dist/team/state/mailbox.d.ts +1 -0
  214. package/dist/team/state/mailbox.d.ts.map +1 -1
  215. package/dist/team/state/mailbox.js +54 -8
  216. package/dist/team/state/mailbox.js.map +1 -1
  217. package/dist/team/state-root.d.ts +1 -1
  218. package/dist/team/state-root.d.ts.map +1 -1
  219. package/dist/team/state-root.js +8 -3
  220. package/dist/team/state-root.js.map +1 -1
  221. package/dist/team/state.d.ts.map +1 -1
  222. package/dist/team/state.js +66 -3
  223. package/dist/team/state.js.map +1 -1
  224. package/dist/team/tmux-session.d.ts.map +1 -1
  225. package/dist/team/tmux-session.js +69 -27
  226. package/dist/team/tmux-session.js.map +1 -1
  227. package/dist/utils/__tests__/platform-command.test.js +101 -2
  228. package/dist/utils/__tests__/platform-command.test.js.map +1 -1
  229. package/dist/utils/git-layout.d.ts +8 -0
  230. package/dist/utils/git-layout.d.ts.map +1 -0
  231. package/dist/utils/git-layout.js +58 -0
  232. package/dist/utils/git-layout.js.map +1 -0
  233. package/dist/utils/platform-command.d.ts.map +1 -1
  234. package/dist/utils/platform-command.js +32 -1
  235. package/dist/utils/platform-command.js.map +1 -1
  236. package/package.json +6 -6
  237. package/src/scripts/notify-fallback-watcher.ts +96 -58
  238. package/src/scripts/notify-hook/auto-nudge.ts +75 -230
  239. package/src/scripts/notify-hook/managed-tmux.ts +324 -0
  240. package/src/scripts/notify-hook/ralph-session-resume.ts +337 -0
  241. package/src/scripts/notify-hook/state-io.ts +2 -10
  242. package/src/scripts/notify-hook/team-dispatch.ts +70 -54
  243. package/src/scripts/notify-hook/team-leader-nudge.ts +19 -5
  244. package/src/scripts/notify-hook/team-tmux-guard.ts +0 -20
  245. package/src/scripts/notify-hook/team-worker.ts +4 -4
  246. package/src/scripts/notify-hook/tmux-injection.ts +103 -33
  247. package/src/scripts/notify-hook.ts +150 -21
  248. package/src/scripts/tmux-hook-engine.ts +4 -0
package/Cargo.lock CHANGED
@@ -32,11 +32,11 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
32
32
 
33
33
  [[package]]
34
34
  name = "omx-explore-harness"
35
- version = "0.11.12"
35
+ version = "0.11.13"
36
36
 
37
37
  [[package]]
38
38
  name = "omx-mux"
39
- version = "0.11.12"
39
+ version = "0.11.13"
40
40
  dependencies = [
41
41
  "serde",
42
42
  "serde_json",
@@ -44,7 +44,7 @@ dependencies = [
44
44
 
45
45
  [[package]]
46
46
  name = "omx-runtime"
47
- version = "0.11.12"
47
+ version = "0.11.13"
48
48
  dependencies = [
49
49
  "omx-mux",
50
50
  "omx-runtime-core",
@@ -53,7 +53,7 @@ dependencies = [
53
53
 
54
54
  [[package]]
55
55
  name = "omx-runtime-core"
56
- version = "0.11.12"
56
+ version = "0.11.13"
57
57
  dependencies = [
58
58
  "fs2",
59
59
  "serde",
@@ -62,7 +62,7 @@ dependencies = [
62
62
 
63
63
  [[package]]
64
64
  name = "omx-sparkshell"
65
- version = "0.11.12"
65
+ version = "0.11.13"
66
66
  dependencies = [
67
67
  "omx-mux",
68
68
  ]
package/Cargo.toml CHANGED
@@ -10,7 +10,7 @@ resolver = "2"
10
10
 
11
11
  [workspace.package]
12
12
 
13
- version = "0.11.12"
13
+ version = "0.11.13"
14
14
 
15
15
  edition = "2021"
16
16
  license = "MIT"
package/README.md CHANGED
@@ -22,6 +22,29 @@ It keeps Codex as the execution engine and makes it easier to:
22
22
  - invoke the canonical skills with `$deep-interview`, `$ralplan`, `$team`, and `$ralph`
23
23
  - keep project guidance, plans, logs, and state in `.omx/`
24
24
 
25
+ ## Core Maintainers
26
+
27
+ | Role | Name | GitHub |
28
+ | --- | --- | --- |
29
+ | Creator & Lead | Yeachan Heo | [@Yeachan-Heo](https://github.com/Yeachan-Heo) |
30
+ | Maintainer | HaD0Yun | [@HaD0Yun](https://github.com/HaD0Yun) |
31
+
32
+ ## Ambassadors
33
+
34
+ | Name | GitHub |
35
+ | --- | --- |
36
+ | Sigrid Jin | [@sigridjineth](https://github.com/sigridjineth) |
37
+
38
+ ## Top Collaborators
39
+
40
+ | Name | GitHub |
41
+ | --- | --- |
42
+ | HaD0Yun | [@HaD0Yun](https://github.com/HaD0Yun) |
43
+ | Junho Yeo | [@junhoyeo](https://github.com/junhoyeo) |
44
+ | JiHongKim98 | [@JiHongKim98](https://github.com/JiHongKim98) |
45
+ | Lor | — |
46
+ | HyunjunJeon | [@HyunjunJeon](https://github.com/HyunjunJeon) |
47
+
25
48
  ## Recommended default flow
26
49
 
27
50
  If you want the default OMX experience, start here:
package/README.vi.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <p align="center">
4
4
  <img src="https://yeachan-heo.github.io/oh-my-codex-website/omx-character-nobg.png" alt="oh-my-codex character" width="280">
5
5
  <br>
6
- <em>Codex của bạn không đơn độc.</em>
6
+ <em>Dùng Codex hiệu quả hơn OMX lo phần prompt, workflow và runtime khi dự án phức tạp dần.</em>
7
7
  </p>
8
8
 
9
9
  [![npm version](https://img.shields.io/npm/v/oh-my-codex)](https://www.npmjs.com/package/oh-my-codex)
@@ -11,253 +11,212 @@
11
11
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
12
12
  [![Discord](https://img.shields.io/discord/1452487457085063218?color=5865F2&logo=discord&logoColor=white&label=Discord)](https://discord.gg/PUwSMR9XNk)
13
13
 
14
- > **[Website](https://yeachan-heo.github.io/oh-my-codex-website/)** | **[Documentation](https://yeachan-heo.github.io/oh-my-codex-website/docs.html)** | **[CLI Reference](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#cli-reference)** | **[Workflows](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#workflows)** | **[Hướng dẫn tích hợp OpenClaw](./docs/openclaw-integration.vi.md)** | **[GitHub](https://github.com/Yeachan-Heo/oh-my-codex)** | **[npm](https://www.npmjs.com/package/oh-my-codex)**
14
+ **Website:** https://yeachan-heo.github.io/oh-my-codex-website/
15
+ **Tài liệu:** [Bắt đầu](./docs/getting-started.html) · [Agent](./docs/agents.html) · [Skill](./docs/skills.html) · [Tích hợp](./docs/integrations.html) · [Demo](./DEMO.md) · [Hướng dẫn OpenClaw](./docs/openclaw-integration.md)
15
16
 
16
- Lớp điều phối đa tác nhân cho [OpenAI Codex CLI](https://github.com/openai/codex).
17
+ OMX lớp workflow mở rộng cho [OpenAI Codex CLI](https://github.com/openai/codex).
17
18
 
18
- ## Điểm mới trong v0.9.0 Spark Initiative
19
+ Codex vẫn engine chính, OMX giúp bạn:
20
+ - cấu hình Codex tốt hơn ngay từ phiên đầu tiên
21
+ - chạy workflow nhất quán từ làm rõ yêu cầu đến hoàn thành
22
+ - gọi các skill chính bằng `$deep-interview`, `$ralplan`, `$team` và `$ralph`
23
+ - lưu trữ hướng dẫn dự án, kế hoạch, log và trạng thái trong `.omx/`
19
24
 
20
- Spark Initiative bản phát hành tăng cường đường đi native cho khám phá và kiểm tra trong OMX.
25
+ ## Workflow mặc định
21
26
 
22
- - **Native harness cho `omx explore`** — chạy khám phá kho mã chỉ đọc nhanh hơn chặt chẽ hơn bằng harness Rust.
23
- - **`omx sparkshell`** — bề mặt kiểm tra native cho operator, hỗ trợ tóm tắt đầu ra dài và chụp tmux pane.
24
- - **Tài sản phát hành native đa nền tảng** — đường hydration cho `omx-explore-harness`, `omx-sparkshell` và `native-release-manifest.json` nay đã nằm trong pipeline phát hành.
25
- - **CI/CD được tăng cường** — thêm thiết lập Rust toolchain tường minh cho `build` job cùng với `cargo fmt --check` và `cargo clippy -- -D warnings`.
27
+ Nếu bạn muốn trải nghiệm OMX nhanh nhất, bắt đầu từ đây:
26
28
 
27
- Xem thêm tại [ghi chú phát hành v0.9.0](./docs/release-notes-0.9.0.md) và [release body](./docs/release-body-0.9.0.md).
28
-
29
- ## Phiên đầu tiên
29
+ ```bash
30
+ npm install -g @openai/codex oh-my-codex
31
+ omx setup
32
+ omx --madmax --high
33
+ ```
30
34
 
31
- Trong Codex:
35
+ Sau đó làm việc bình thường trong Codex:
32
36
 
33
37
  ```text
34
- $deep-interview "clarify the auth change"
38
+ $deep-interview "clarify the authentication change"
35
39
  $ralplan "approve the auth plan and review tradeoffs"
36
40
  $ralph "carry the approved plan to completion"
37
41
  $team 3:executor "execute the approved plan in parallel"
38
42
  ```
39
43
 
40
- Từ terminal:
44
+ Đó là flow chính.
45
+ Khởi động OMX, làm rõ yêu cầu khi cần, duyệt kế hoạch, rồi chọn `$team` để chạy song song hoặc `$ralph` để một agent lo đến khi xong.
41
46
 
42
- ```bash
43
- omx team 4:executor "parallelize a multi-module refactor"
44
- omx team status <team-name>
45
- omx team shutdown <team-name>
46
- ```
47
+ ## OMX dùng để làm gì
47
48
 
48
- ## Quy trình được khuyến nghị
49
+ Dùng OMX nếu bạn đã quen Codex và muốn trải nghiệm tốt hơn:
50
+ - workflow chuẩn xoay quanh `$deep-interview`, `$ralplan`, `$team` và `$ralph`
51
+ - các role chuyên biệt và skill hỗ trợ cho từng loại task
52
+ - hướng dẫn dự án qua `AGENTS.md` theo scope
53
+ - lưu trạng thái lâu dài trong `.omx/` — kế hoạch, log, memory và theo dõi mode
49
54
 
50
- 1. `$deep-interview` khi phạm vi hoặc ranh giới vẫn chưa rõ.
51
- 2. `$ralplan` — để biến phạm vi đã làm rõ thành kế hoạch kiến trúc và triển khai đã được chốt.
52
- 3. `$team` hoặc `$ralph` — dùng `$team` cho thực thi song song có phối hợp, hoặc `$ralph` cho vòng lặp bền bỉ để hoàn tất/xác minh với một chủ sở hữu duy nhất.
55
+ Nếu bạn chỉ muốn dùng Codex thuần không cần thêm workflow, thì có lẽ không cần OMX.
53
56
 
54
- ## hình cốt lõi
57
+ ## Bắt đầu nhanh
55
58
 
56
- OMX cài đặt và kết nối các lớp sau:
59
+ ### Yêu cầu
57
60
 
58
- ```text
59
- User
60
- -> Codex CLI
61
- -> AGENTS.md (bộ não điều phối)
62
- -> ~/.codex/prompts/*.md (danh mục prompt tác nhân)
63
- -> ~/.codex/skills/*/SKILL.md (danh mục skill)
64
- -> ~/.codex/config.toml (tính năng, thông báo, MCP)
65
- -> .omx/ (trạng thái runtime, bộ nhớ, kế hoạch, nhật ký)
66
- ```
61
+ - Node.js 20+
62
+ - Codex CLI đã cài: `npm install -g @openai/codex`
63
+ - Codex đã xác thực (auth)
64
+ - `tmux` trên macOS/Linux nếu muốn dùng team runtime
65
+ - `psmux` trên Windows nếu muốn dùng team mode
66
+
67
+ ### Phiên đầu tiên
67
68
 
68
- ## Các lệnh chính
69
+ Khởi chạy OMX:
69
70
 
70
71
  ```bash
71
- omx # Khởi chạy Codex (+ HUD trong tmux khi có sẵn)
72
- omx setup # Cài đặt prompt/skill/config theo phạm vi + .omx của dự án + AGENTS.md theo phạm vi
73
- omx doctor # Chẩn đoán cài đặt/runtime
74
- omx doctor --team # Chẩn đoán Team/swarm
75
- omx team ... # Khởi động/trạng thái/tiếp tục/tắt worker tmux của đội
76
- omx status # Hiển thị các chế độ đang hoạt động
77
- omx cancel # Hủy các chế độ thực thi đang hoạt động
78
- omx reasoning <mode> # low|medium|high|xhigh
79
- omx tmux-hook ... # init|status|validate|test
80
- omx hooks ... # init|status|validate|test (quy trình mở rộng plugin)
81
- omx hud ... # --watch|--json|--preset
82
- omx help
72
+ omx --madmax --high
83
73
  ```
84
74
 
85
- ## Mở rộng Hooks (Bề mặt bổ sung)
75
+ Rồi thử workflow chính:
86
76
 
87
- OMX hiện bao gồm `omx hooks` cho scaffolding và xác thực plugin.
88
-
89
- - `omx tmux-hook` vẫn được hỗ trợ và không thay đổi.
90
- - `omx hooks` bổ sung và không thay thế quy trình tmux-hook.
91
- - Tệp plugin nằm tại `.omx/hooks/*.mjs`.
92
- - Plugin tắt theo mặc định; kích hoạt bằng `OMX_HOOK_PLUGINS=1`.
93
-
94
- Xem `docs/hooks-extension.md` cho quy trình mở rộng đầy đủ và mô hình sự kiện.
95
-
96
- ## Cờ khởi chạy
97
-
98
- ```bash
99
- --yolo
100
- --high
101
- --xhigh
102
- --madmax
103
- --force
104
- --dry-run
105
- --verbose
106
- --scope <user|project> # chỉ dành cho setup
77
+ ```text
78
+ $deep-interview "clarify the authentication change"
79
+ $ralplan "approve the safest implementation path"
80
+ $ralph "carry the approved plan to completion"
81
+ $team 3:executor "execute the approved plan in parallel"
107
82
  ```
108
83
 
109
- `--madmax` ánh xạ đến Codex `--dangerously-bypass-approvals-and-sandbox`.
110
- Chỉ sử dụng trong môi trường sandbox tin cậy hoặc bên ngoài.
84
+ Dùng `$team` khi cần nhiều worker chạy song song, hoặc `$ralph` khi muốn một agent lo từ đầu đến cuối.
111
85
 
112
- ### Chính sách workingDirectory MCP (tăng cường tùy chọn)
86
+ ## hình đơn giản
113
87
 
114
- Theo mặc định, các công cụ MCP state/memory/trace chấp nhận `workingDirectory` do người gọi cung cấp.
115
- Để hạn chế điều này, đặt danh sách gốc được phép:
88
+ OMX **không** thay thế Codex.
116
89
 
117
- ```bash
118
- export OMX_MCP_WORKDIR_ROOTS="/path/to/project:/path/to/another-root"
119
- ```
90
+ OMX bổ sung một lớp hỗ trợ phía trên Codex:
91
+ - **Codex** vẫn làm toàn bộ việc thực thi
92
+ - **Role của OMX** giúp gọi nhanh các vai trò chuyên biệt
93
+ - **Skill của OMX** đóng gói các workflow phổ biến thành lệnh
94
+ - **`.omx/`** lưu kế hoạch, log, memory và trạng thái runtime
120
95
 
121
- Khi được đặt, các giá trị `workingDirectory` ngoài các gốc này sẽ bị từ chối.
96
+ Nói đơn giản: OMX giúp **phân task đúng chỗ + workflow ràng + runtime ổn định hơn** — không phải một bảng điều khiển để gõ lệnh cả ngày.
122
97
 
123
- ## Kiểm soát Prompt Codex-First
98
+ ## Hướng dẫn cho người mới
124
99
 
125
- Theo mặc định, OMX tiêm:
100
+ 1. Chạy `omx setup`
101
+ 2. Khởi động với `omx --madmax --high`
102
+ 3. Dùng `$deep-interview "..."` khi yêu cầu còn mơ hồ
103
+ 4. Dùng `$ralplan "..."` để duyệt kế hoạch và cân nhắc trade-off
104
+ 5. Chọn `$team` để chạy song song hoặc `$ralph` để một agent lo đến khi xong
126
105
 
127
- ```text
128
- -c model_instructions_file="<cwd>/AGENTS.md"
129
- ```
130
-
131
- Điều này kết hợp `AGENTS.md` trong `CODEX_HOME` với `AGENTS.md` của dự án (nếu có), rồi thêm lớp phủ runtime.
132
- Mở rộng hành vi Codex, nhưng không thay thế/bỏ qua các chính sách hệ thống cốt lõi của Codex.
106
+ ## Workflow khuyến nghị
133
107
 
134
- Điều khiển:
108
+ 1. `$deep-interview` — làm rõ scope khi yêu cầu còn mơ hồ.
109
+ 2. `$ralplan` — chuyển scope đã rõ thành kế hoạch triển khai được duyệt.
110
+ 3. `$team` hoặc `$ralph` — dùng `$team` khi cần nhiều worker song song, hoặc `$ralph` khi muốn một agent chạy liên tục đến khi xong.
135
111
 
136
- ```bash
137
- OMX_BYPASS_DEFAULT_SYSTEM_PROMPT=0 omx # tắt tiêm AGENTS.md
138
- OMX_MODEL_INSTRUCTIONS_FILE=/path/to/instructions.md omx
139
- ```
112
+ ## Các lệnh thường dùng trong phiên
140
113
 
141
- ## Chế độ đội
114
+ | Lệnh | Dùng khi |
115
+ | --- | --- |
116
+ | `$deep-interview "..."` | Làm rõ ý định, scope và non-goal |
117
+ | `$ralplan "..."` | Duyệt kế hoạch triển khai và trade-off |
118
+ | `$ralph "..."` | Chạy liên tục đến khi hoàn thành và verify |
119
+ | `$team "..."` | Chạy song song khi task đủ lớn |
120
+ | `/skills` | Xem danh sách skill và helper đã cài |
142
121
 
143
- Sử dụng chế độ đội cho công việc lớn được hưởng lợi từ worker song song.
122
+ ## Nâng cao
144
123
 
145
- Vòng đời:
124
+ Các phần dưới đây hữu ích nhưng không phải là bước bắt đầu chính.
146
125
 
147
- ```text
148
- start -> assign scoped lanes -> monitor -> verify terminal tasks -> shutdown
149
- ```
126
+ ### Team runtime
150
127
 
151
- Các lệnh vận hành:
128
+ Dùng team runtime khi cần phối hợp nhiều worker qua tmux/worktree — đây không phải bước bắt đầu mặc định.
152
129
 
153
130
  ```bash
154
- omx team <args>
131
+ omx team 3:executor "fix the failing tests with verification"
155
132
  omx team status <team-name>
156
133
  omx team resume <team-name>
157
134
  omx team shutdown <team-name>
158
135
  ```
159
136
 
160
- Quy tắc quan trọng: không tắt khi các tác vụ vẫn đang ở trạng thái `in_progress` trừ khi đang hủy bỏ.
161
-
162
- ### Team shutdown policy
137
+ ### Setup, doctor HUD
163
138
 
164
- Use `omx team shutdown <team-name>` after the team reaches a terminal state.
165
- Team cleanup now follows one standalone path; legacy linked-Ralph shutdown handling is no longer a separate public workflow.
139
+ Đây các công cụ vận hành/hỗ trợ:
140
+ - `omx setup` cài prompt, skill, config scaffold AGENTS
141
+ - `omx doctor` kiểm tra cài đặt khi có vấn đề
142
+ - `omx hud --watch` theo dõi trạng thái, không phải workflow chính
166
143
 
167
- Chọn Worker CLI cho worker của đội:
144
+ ### Explore sparkshell
168
145
 
169
- ```bash
170
- OMX_TEAM_WORKER_CLI=auto # mặc định; sử dụng claude khi worker --model chứa "claude"
171
- OMX_TEAM_WORKER_CLI=codex # ép buộc worker Codex CLI
172
- OMX_TEAM_WORKER_CLI=claude # ép buộc worker Claude CLI
173
- OMX_TEAM_WORKER_CLI_MAP=codex,codex,claude,claude # hỗn hợp CLI theo worker (độ dài=1 hoặc số worker)
174
- OMX_TEAM_AUTO_INTERRUPT_RETRY=0 # tùy chọn: tắt fallback thích ứng queue->resend
175
- ```
176
-
177
- Lưu ý:
178
- - Tham số khởi chạy worker vẫn được chia sẻ qua `OMX_TEAM_WORKER_LAUNCH_ARGS`.
179
- - `OMX_TEAM_WORKER_CLI_MAP` ghi đè `OMX_TEAM_WORKER_CLI` cho lựa chọn theo worker.
180
- - Gửi trigger sử dụng thử lại thích ứng theo mặc định (queue/submit, sau đó fallback an toàn clear-line+resend khi cần).
181
- - Trong chế độ Claude worker, OMX khởi chạy worker dưới dạng `claude` thuần túy (không có tham số khởi chạy thêm) và bỏ qua các ghi đè rõ ràng `--model` / `--config` / `--effort` để Claude sử dụng `settings.json` mặc định.
182
-
183
- ## `omx setup` ghi những gì
184
-
185
- - `.omx/setup-scope.json` (phạm vi cài đặt được lưu trữ)
186
- - Cài đặt phụ thuộc phạm vi:
187
- - `user`: `~/.codex/prompts/`, `~/.codex/skills/`, `~/.codex/config.toml`, `~/.omx/agents/`, `~/.codex/AGENTS.md`
188
- - `project`: `./.codex/prompts/`, `./.codex/skills/`, `./.codex/config.toml`, `./.omx/agents/`, `./AGENTS.md`
189
- - Hành vi khởi chạy: nếu phạm vi được lưu trữ là `project`, khởi chạy `omx` tự động sử dụng `CODEX_HOME=./.codex` (trừ khi `CODEX_HOME` đã được đặt).
190
- - Hướng dẫn khởi chạy sẽ kết hợp `~/.codex/AGENTS.md` (hoặc `CODEX_HOME/AGENTS.md` nếu đã ghi đè) với `./AGENTS.md` của dự án, rồi thêm lớp phủ runtime.
191
- - Các tệp `AGENTS.md` hiện có sẽ không bao giờ bị ghi đè âm thầm: ở TTY tương tác, setup hỏi trước khi thay thế; ở chế độ không tương tác, việc thay thế sẽ bị bỏ qua trừ khi dùng `--force` (kiểm tra an toàn phiên hoạt động vẫn áp dụng).
192
- - Cập nhật `config.toml` (cho cả hai phạm vi):
193
- - `notify = ["node", "..."]`
194
- - `model_reasoning_effort = "high"`
195
- - `developer_instructions = "..."`
196
- - `[features] multi_agent = true, child_agents_md = true`
197
- - Mục máy chủ MCP (`omx_state`, `omx_memory`, `omx_code_intel`, `omx_trace`)
198
- - `[tui] status_line`
199
- - `AGENTS.md` theo phạm vi
200
- - Thư mục `.omx/` runtime và cấu hình HUD
201
-
202
- ## Tác nhân và skill
203
-
204
- - Prompt: `prompts/*.md` (cài vào `~/.codex/prompts/` cho `user`, `./.codex/prompts/` cho `project`)
205
- - Skill: `skills/*/SKILL.md` (cài vào `~/.codex/skills/` cho `user`, `./.codex/skills/` cho `project`)
146
+ - `omx explore --prompt "..."` tìm kiếm chỉ đọc trong repository
147
+ - `omx sparkshell <command>` chạy lệnh shell kiểm soát output
206
148
 
207
149
  Ví dụ:
208
- - Tác nhân: `architect`, `planner`, `executor`, `debugger`, `verifier`, `security-reviewer`
209
- - Skill: `deep-interview`, `ralplan`, `team`, `ralph`, `plan`, `cancel`
210
-
211
- ## Cấu trúc dự án
212
150
 
213
- ```text
214
- oh-my-codex/
215
- bin/omx.js
216
- src/
217
- cli/
218
- team/
219
- mcp/
220
- hooks/
221
- hud/
222
- config/
223
- modes/
224
- notifications/
225
- verification/
226
- prompts/
227
- skills/
228
- templates/
229
- scripts/
151
+ ```bash
152
+ omx explore --prompt "find where team state is written"
153
+ omx sparkshell git status
154
+ omx sparkshell --tmux-pane %12 --tail-lines 400
230
155
  ```
231
156
 
232
- ## Phát triển
157
+ ### Cài tmux theo nền tảng
233
158
 
234
- ```bash
235
- git clone https://github.com/Yeachan-Heo/oh-my-codex.git
236
- cd oh-my-codex
237
- npm install
238
- npm run build
239
- npm test
240
- ```
159
+ `omx team` cần backend tương thích tmux:
241
160
 
242
- ## Tài liệu
161
+ | Nền tảng | Cài đặt |
162
+ | --- | --- |
163
+ | macOS | `brew install tmux` |
164
+ | Ubuntu/Debian | `sudo apt install tmux` |
165
+ | Fedora | `sudo dnf install tmux` |
166
+ | Arch | `sudo pacman -S tmux` |
167
+ | Windows | `winget install psmux` |
168
+ | Windows (WSL2) | `sudo apt install tmux` |
243
169
 
244
- - **[Tài liệu đầy đủ](https://yeachan-heo.github.io/oh-my-codex-website/docs.html)** — Hướng dẫn hoàn chỉnh
245
- - **[Tham chiếu CLI](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#cli-reference)** — Tất cả lệnh `omx`, cờ và công cụ
246
- - **[Hướng dẫn thông báo](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#notifications)** — Cài đặt Discord, Telegram, Slack và webhook
247
- - **[Quy trình công việc khuyến nghị](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#workflows)** — Chuỗi skill đã thử nghiệm thực chiến cho các tác vụ phổ biến
248
- - **[Ghi chú phát hành](https://yeachan-heo.github.io/oh-my-codex-website/docs.html#release-notes)** — Tính năng mới trong mỗi phiên bản
170
+ ## Vấn đề đã biết
249
171
 
250
- ## Ghi chú
172
+ ### Intel Mac: CPU `syspolicyd` / `trustd` cao khi khởi động
251
173
 
252
- - Nhật thay đổi đầy đủ: `CHANGELOG.md`
253
- - Hướng dẫn di chuyển (sau v0.4.4 mainline): `docs/migration-mainline-post-v0.4.4.md`
254
- - Ghi chú về độ bao phủ và tương đương: `COVERAGE.md`
255
- - Quy trình mở rộng hook: `docs/hooks-extension.md`
256
- - Chi tiết cài đặt và đóng góp: `CONTRIBUTING.md`
174
+ Trên một số máy Intel Mac, khi khởi động OMX — đặc biệt với `--madmax --high` — CPU có thể tăng đột biến do macOS Gatekeeper xác thực nhiều tiến trình đồng thời.
257
175
 
258
- ## Lời cảm ơn
176
+ Nếu gặp tình trạng này, thử:
177
+ - `xattr -dr com.apple.quarantine $(which omx)`
178
+ - Thêm ứng dụng terminal vào danh sách Developer Tools trong cài đặt Security của macOS
179
+ - Dùng cấu hình nhẹ hơn (bỏ `--madmax --high`)
180
+
181
+ ## Tài liệu
259
182
 
260
- Lấy cảm hứng từ [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode), được điều chỉnh cho Codex CLI.
183
+ - [Bắt đầu](./docs/getting-started.html)
184
+ - [Hướng dẫn demo](./DEMO.md)
185
+ - [Danh mục agent](./docs/agents.html)
186
+ - [Tham chiếu skill](./docs/skills.html)
187
+ - [Tích hợp](./docs/integrations.html)
188
+ - [Hướng dẫn OpenClaw / notification gateway](./docs/openclaw-integration.md)
189
+ - [Đóng góp](./CONTRIBUTING.md)
190
+ - [Nhật ký thay đổi](./CHANGELOG.md)
191
+
192
+ ## Ngôn ngữ
193
+
194
+ - [English](./README.md)
195
+ - [한국어](./README.ko.md)
196
+ - [日本語](./README.ja.md)
197
+ - [简体中文](./README.zh.md)
198
+ - [繁體中文](./README.zh-TW.md)
199
+ - [Tiếng Việt](./README.vi.md)
200
+ - [Español](./README.es.md)
201
+ - [Português](./README.pt.md)
202
+ - [Русский](./README.ru.md)
203
+ - [Türkçe](./README.tr.md)
204
+ - [Deutsch](./README.de.md)
205
+ - [Français](./README.fr.md)
206
+ - [Italiano](./README.it.md)
207
+ - [Ελληνικά](./README.el.md)
208
+ - [Polski](./README.pl.md)
209
+
210
+ ## Đóng góp
211
+
212
+ | Vai trò | Tên | GitHub |
213
+ | --- | --- | --- |
214
+ | Tác giả & Lead | Yeachan Heo | [@Yeachan-Heo](https://github.com/Yeachan-Heo) |
215
+ | Maintainer | HaD0Yun | [@HaD0Yun](https://github.com/HaD0Yun) |
216
+
217
+ ## Star History
218
+
219
+ [![Star History Chart](https://api.star-history.com/svg?repos=Yeachan-Heo/oh-my-codex&type=date&legend=top-left)](https://www.star-history.com/#Yeachan-Heo/oh-my-codex&type=date&legend=top-left)
261
220
 
262
221
  ## Giấy phép
263
222
 
@@ -173,6 +173,7 @@ impl RuntimeEngine {
173
173
  message_id,
174
174
  from_worker,
175
175
  to_worker,
176
+ body: Some(body),
176
177
  }
177
178
  }
178
179
  RuntimeCommand::MarkMailboxNotified { message_id } => {
@@ -293,7 +294,10 @@ impl RuntimeEngine {
293
294
  lock_file.lock_shared()?;
294
295
 
295
296
  let events_json = std::fs::read_to_string(dir.join("events.json"))?;
296
- let events: Vec<RuntimeEvent> = serde_json::from_str(&events_json)?;
297
+ let mut events: Vec<RuntimeEvent> = serde_json::from_str(&events_json)?;
298
+ let mailbox = std::fs::read_to_string(dir.join("mailbox.json"))
299
+ .ok()
300
+ .and_then(|mailbox_json| serde_json::from_str::<MailboxLog>(&mailbox_json).ok());
297
301
 
298
302
  drop(lock_file);
299
303
 
@@ -302,6 +306,32 @@ impl RuntimeEngine {
302
306
  for event in &events {
303
307
  replay_event(&mut engine, event);
304
308
  }
309
+
310
+ if let Some(mailbox_state) = mailbox {
311
+ let body_by_message_id: std::collections::HashMap<&str, &str> = mailbox_state
312
+ .records()
313
+ .iter()
314
+ .map(|record| (record.message_id.as_str(), record.body.as_str()))
315
+ .collect();
316
+
317
+ for event in &mut events {
318
+ if let RuntimeEvent::MailboxMessageCreated {
319
+ message_id, body, ..
320
+ } = event
321
+ {
322
+ if body.is_none() {
323
+ if let Some(record_body) = body_by_message_id.get(message_id.as_str()) {
324
+ if !record_body.is_empty() {
325
+ *body = Some((*record_body).to_string());
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ engine.mailbox = mailbox_state;
333
+ }
334
+
305
335
  engine.event_log = events;
306
336
 
307
337
  Ok(engine)
@@ -357,10 +387,14 @@ fn replay_event(engine: &mut RuntimeEngine, event: &RuntimeEvent) {
357
387
  message_id,
358
388
  from_worker,
359
389
  to_worker,
390
+ body,
360
391
  } => {
361
- engine
362
- .mailbox
363
- .create(message_id, from_worker, to_worker, "");
392
+ engine.mailbox.create(
393
+ message_id,
394
+ from_worker,
395
+ to_worker,
396
+ body.as_deref().unwrap_or(""),
397
+ );
364
398
  }
365
399
  RuntimeEvent::MailboxNotified { message_id } => {
366
400
  let _ = engine.mailbox.mark_notified(message_id);
@@ -515,6 +549,90 @@ mod tests {
515
549
  let _ = std::fs::remove_dir_all(&dir);
516
550
  }
517
551
 
552
+ #[test]
553
+ fn persist_and_load_round_trip_preserves_mailbox_body() {
554
+ let dir = std::env::temp_dir().join("omx-runtime-test-mailbox-body");
555
+ let _ = std::fs::remove_dir_all(&dir);
556
+
557
+ let mut engine = RuntimeEngine::new().with_state_dir(&dir);
558
+ engine
559
+ .process(RuntimeCommand::CreateMailboxMessage {
560
+ message_id: "msg-1".into(),
561
+ from_worker: "worker-1".into(),
562
+ to_worker: "leader-fixed".into(),
563
+ body: "ACK: worker-1 initialized".into(),
564
+ })
565
+ .unwrap();
566
+ engine.persist().unwrap();
567
+
568
+ let loaded = RuntimeEngine::load(&dir).unwrap();
569
+ loaded.write_compatibility_view().unwrap();
570
+
571
+ let mailbox_json = std::fs::read_to_string(dir.join("mailbox.json")).unwrap();
572
+ let mailbox: serde_json::Value = serde_json::from_str(&mailbox_json).unwrap();
573
+ assert_eq!(
574
+ mailbox["records"][0]["body"],
575
+ serde_json::Value::String("ACK: worker-1 initialized".into())
576
+ );
577
+
578
+ let _ = std::fs::remove_dir_all(&dir);
579
+ }
580
+
581
+ #[test]
582
+ fn load_backfills_legacy_mailbox_event_body_from_mailbox_json() {
583
+ let dir = std::env::temp_dir().join("omx-runtime-test-mailbox-backfill");
584
+ let _ = std::fs::remove_dir_all(&dir);
585
+ std::fs::create_dir_all(&dir).unwrap();
586
+
587
+ std::fs::write(
588
+ dir.join("events.json"),
589
+ serde_json::to_string_pretty(&vec![RuntimeEvent::MailboxMessageCreated {
590
+ message_id: "msg-legacy".into(),
591
+ from_worker: "worker-1".into(),
592
+ to_worker: "leader-fixed".into(),
593
+ body: None,
594
+ }])
595
+ .unwrap(),
596
+ )
597
+ .unwrap();
598
+ std::fs::write(
599
+ dir.join("mailbox.json"),
600
+ serde_json::to_string_pretty(&serde_json::json!({
601
+ "records": [{
602
+ "message_id": "msg-legacy",
603
+ "from_worker": "worker-1",
604
+ "to_worker": "leader-fixed",
605
+ "body": "recovered body",
606
+ "created_at": "2026-04-04T00:00:00.000Z",
607
+ "notified_at": null,
608
+ "delivered_at": null
609
+ }]
610
+ }))
611
+ .unwrap(),
612
+ )
613
+ .unwrap();
614
+ std::fs::write(dir.join("engine.lock"), "").unwrap();
615
+
616
+ let loaded = RuntimeEngine::load(&dir).unwrap();
617
+ loaded.persist().unwrap();
618
+
619
+ let events_json = std::fs::read_to_string(dir.join("events.json")).unwrap();
620
+ let persisted_events: Vec<RuntimeEvent> = serde_json::from_str(&events_json).unwrap();
621
+ assert!(matches!(
622
+ &persisted_events[0],
623
+ RuntimeEvent::MailboxMessageCreated { body: Some(body), .. } if body == "recovered body"
624
+ ));
625
+
626
+ let mailbox_json = std::fs::read_to_string(dir.join("mailbox.json")).unwrap();
627
+ let mailbox: serde_json::Value = serde_json::from_str(&mailbox_json).unwrap();
628
+ assert_eq!(
629
+ mailbox["records"][0]["body"],
630
+ serde_json::Value::String("recovered body".into())
631
+ );
632
+
633
+ let _ = std::fs::remove_dir_all(&dir);
634
+ }
635
+
518
636
  #[test]
519
637
  fn derive_readiness_stale_authority() {
520
638
  let mut authority = AuthorityLease::new();