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.
- package/Cargo.lock +5 -5
- package/Cargo.toml +1 -1
- package/README.md +23 -0
- package/README.vi.md +144 -185
- package/crates/omx-runtime-core/src/engine.rs +122 -4
- package/crates/omx-runtime-core/src/lib.rs +17 -0
- package/dist/cli/__tests__/autoresearch.test.js +11 -0
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
- package/dist/cli/__tests__/cleanup.test.js +117 -4
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js +13 -0
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +6 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +94 -1
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +3 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +10 -0
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/packaged-script-resolution.test.js +4 -3
- package/dist/cli/__tests__/packaged-script-resolution.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +6 -0
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +29 -12
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/star-prompt.test.js +16 -0
- package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +112 -1
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +2 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +1 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +30 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -0
- package/dist/cli/cleanup.d.ts +2 -0
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +26 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +161 -50
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +15 -14
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/star-prompt.d.ts.map +1 -1
- package/dist/cli/star-prompt.js +1 -0
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +5 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +26 -0
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +1 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +4 -4
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/mcp-registry.test.js +13 -16
- package/dist/config/__tests__/mcp-registry.test.js.map +1 -1
- package/dist/config/mcp-registry.d.ts +1 -0
- package/dist/config/mcp-registry.d.ts.map +1 -1
- package/dist/config/mcp-registry.js +4 -4
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/config/models.d.ts +1 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +39 -1
- package/dist/config/models.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +12 -1
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +499 -17
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +140 -14
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +5 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +597 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +15 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +73 -53
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +193 -2
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +183 -0
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +255 -97
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +46 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +1 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +48 -0
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1 -0
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +70 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +10 -37
- package/dist/hud/state.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +5 -0
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +46 -0
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +4 -0
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +2 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js +84 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +1 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js +55 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/notifications/idle-cooldown.d.ts +8 -6
- package/dist/notifications/idle-cooldown.d.ts.map +1 -1
- package/dist/notifications/idle-cooldown.js +53 -22
- package/dist/notifications/idle-cooldown.js.map +1 -1
- package/dist/notifications/notifier.js +1 -1
- package/dist/notifications/notifier.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +1 -0
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/openclaw/config.js +2 -2
- package/dist/openclaw/config.js.map +1 -1
- package/dist/runtime/bridge.d.ts +1 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +2 -6
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +97 -59
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +72 -238
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts +19 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -0
- package/dist/scripts/notify-hook/managed-tmux.js +320 -0
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -0
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +22 -0
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js +277 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -0
- package/dist/scripts/notify-hook/state-io.d.ts +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +2 -10
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +60 -59
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +13 -5
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +1 -19
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +4 -4
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +102 -35
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +144 -20
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts +1 -0
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +3 -0
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +96 -4
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/leader-activity.test.js +107 -2
- package/dist/team/__tests__/leader-activity.test.js.map +1 -1
- package/dist/team/__tests__/runtime-cli.test.js +32 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +148 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/shutdown-fallback.test.js +13 -0
- package/dist/team/__tests__/shutdown-fallback.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +11 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +16 -5
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +460 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +34 -7
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/commit-hygiene.d.ts +60 -0
- package/dist/team/commit-hygiene.d.ts.map +1 -0
- package/dist/team/commit-hygiene.js +232 -0
- package/dist/team/commit-hygiene.js.map +1 -0
- package/dist/team/leader-activity.d.ts.map +1 -1
- package/dist/team/leader-activity.js +17 -35
- package/dist/team/leader-activity.js.map +1 -1
- package/dist/team/runtime-cli.d.ts +9 -1
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +15 -6
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts +7 -2
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +391 -63
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/state/dispatch.js +1 -1
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/mailbox.d.ts +1 -0
- package/dist/team/state/mailbox.d.ts.map +1 -1
- package/dist/team/state/mailbox.js +54 -8
- package/dist/team/state/mailbox.js.map +1 -1
- package/dist/team/state-root.d.ts +1 -1
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +8 -3
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +66 -3
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +69 -27
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +101 -2
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/git-layout.d.ts +8 -0
- package/dist/utils/git-layout.d.ts.map +1 -0
- package/dist/utils/git-layout.js +58 -0
- package/dist/utils/git-layout.js.map +1 -0
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +32 -1
- package/dist/utils/platform-command.js.map +1 -1
- package/package.json +6 -6
- package/src/scripts/notify-fallback-watcher.ts +96 -58
- package/src/scripts/notify-hook/auto-nudge.ts +75 -230
- package/src/scripts/notify-hook/managed-tmux.ts +324 -0
- package/src/scripts/notify-hook/ralph-session-resume.ts +337 -0
- package/src/scripts/notify-hook/state-io.ts +2 -10
- package/src/scripts/notify-hook/team-dispatch.ts +70 -54
- package/src/scripts/notify-hook/team-leader-nudge.ts +19 -5
- package/src/scripts/notify-hook/team-tmux-guard.ts +0 -20
- package/src/scripts/notify-hook/team-worker.ts +4 -4
- package/src/scripts/notify-hook/tmux-injection.ts +103 -33
- package/src/scripts/notify-hook.ts +150 -21
- 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.
|
|
35
|
+
version = "0.11.13"
|
|
36
36
|
|
|
37
37
|
[[package]]
|
|
38
38
|
name = "omx-mux"
|
|
39
|
-
version = "0.11.
|
|
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.
|
|
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.
|
|
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.
|
|
65
|
+
version = "0.11.13"
|
|
66
66
|
dependencies = [
|
|
67
67
|
"omx-mux",
|
|
68
68
|
]
|
package/Cargo.toml
CHANGED
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
|
|
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
|
[](https://www.npmjs.com/package/oh-my-codex)
|
|
@@ -11,253 +11,212 @@
|
|
|
11
11
|
[](https://nodejs.org)
|
|
12
12
|
[](https://discord.gg/PUwSMR9XNk)
|
|
13
13
|
|
|
14
|
-
|
|
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
|
-
|
|
17
|
+
OMX là lớp workflow mở rộng cho [OpenAI Codex CLI](https://github.com/openai/codex).
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
Codex vẫn là 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
|
-
|
|
25
|
+
## Workflow mặc định
|
|
21
26
|
|
|
22
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g @openai/codex oh-my-codex
|
|
31
|
+
omx setup
|
|
32
|
+
omx --madmax --high
|
|
33
|
+
```
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
Sau đó làm việc bình thường trong Codex:
|
|
32
36
|
|
|
33
37
|
```text
|
|
34
|
-
$deep-interview "clarify the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 mà không cần thêm workflow, thì có lẽ không cần OMX.
|
|
53
56
|
|
|
54
|
-
##
|
|
57
|
+
## Bắt đầu nhanh
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
### Yêu cầu
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
69
|
+
Khởi chạy OMX:
|
|
69
70
|
|
|
70
71
|
```bash
|
|
71
|
-
omx
|
|
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
|
-
|
|
75
|
+
Rồi thử workflow chính:
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
86
|
+
## Mô hình đơn giản
|
|
113
87
|
|
|
114
|
-
|
|
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
|
-
|
|
118
|
-
|
|
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
|
-
|
|
96
|
+
Nói đơn giản: OMX giúp **phân task đúng chỗ + workflow rõ 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
|
-
##
|
|
98
|
+
## Hướng dẫn cho người mới
|
|
124
99
|
|
|
125
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
122
|
+
## Nâng cao
|
|
144
123
|
|
|
145
|
-
|
|
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
|
-
|
|
148
|
-
start -> assign scoped lanes -> monitor -> verify terminal tasks -> shutdown
|
|
149
|
-
```
|
|
126
|
+
### Team runtime
|
|
150
127
|
|
|
151
|
-
|
|
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
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
### Team shutdown policy
|
|
137
|
+
### Setup, doctor và HUD
|
|
163
138
|
|
|
164
|
-
|
|
165
|
-
|
|
139
|
+
Đây là các công cụ vận hành/hỗ trợ:
|
|
140
|
+
- `omx setup` cài prompt, skill, config và 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
|
-
|
|
144
|
+
### Explore và sparkshell
|
|
168
145
|
|
|
169
|
-
|
|
170
|
-
|
|
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 có 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
|
-
```
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
157
|
+
### Cài tmux theo nền tảng
|
|
233
158
|
|
|
234
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
+
### Intel Mac: CPU `syspolicyd` / `trustd` cao khi khởi động
|
|
251
173
|
|
|
252
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
[](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
|
-
|
|
363
|
-
|
|
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();
|