oh-my-codex 0.21.33 → 0.21.35
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 +6 -6
- package/Cargo.toml +1 -1
- package/dist/team/__tests__/runtime.test.js +119 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +23 -0
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/shutdown-preservation.test.d.ts +2 -0
- package/dist/team/__tests__/shutdown-preservation.test.d.ts.map +1 -0
- package/dist/team/__tests__/shutdown-preservation.test.js +747 -0
- package/dist/team/__tests__/shutdown-preservation.test.js.map +1 -0
- package/dist/team/__tests__/worktree.test.js +269 -4
- package/dist/team/__tests__/worktree.test.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +244 -50
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.js +1 -1
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/worktree.d.ts +34 -0
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +237 -4
- package/dist/team/worktree.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
package/Cargo.lock
CHANGED
|
@@ -32,7 +32,7 @@ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
|
32
32
|
|
|
33
33
|
[[package]]
|
|
34
34
|
name = "omx-api"
|
|
35
|
-
version = "0.21.
|
|
35
|
+
version = "0.21.35"
|
|
36
36
|
dependencies = [
|
|
37
37
|
"serde",
|
|
38
38
|
"serde_json",
|
|
@@ -40,14 +40,14 @@ dependencies = [
|
|
|
40
40
|
|
|
41
41
|
[[package]]
|
|
42
42
|
name = "omx-explore-harness"
|
|
43
|
-
version = "0.21.
|
|
43
|
+
version = "0.21.35"
|
|
44
44
|
dependencies = [
|
|
45
45
|
"libc",
|
|
46
46
|
]
|
|
47
47
|
|
|
48
48
|
[[package]]
|
|
49
49
|
name = "omx-mux"
|
|
50
|
-
version = "0.21.
|
|
50
|
+
version = "0.21.35"
|
|
51
51
|
dependencies = [
|
|
52
52
|
"serde",
|
|
53
53
|
"serde_json",
|
|
@@ -55,7 +55,7 @@ dependencies = [
|
|
|
55
55
|
|
|
56
56
|
[[package]]
|
|
57
57
|
name = "omx-runtime"
|
|
58
|
-
version = "0.21.
|
|
58
|
+
version = "0.21.35"
|
|
59
59
|
dependencies = [
|
|
60
60
|
"fs2",
|
|
61
61
|
"libc",
|
|
@@ -67,7 +67,7 @@ dependencies = [
|
|
|
67
67
|
|
|
68
68
|
[[package]]
|
|
69
69
|
name = "omx-runtime-core"
|
|
70
|
-
version = "0.21.
|
|
70
|
+
version = "0.21.35"
|
|
71
71
|
dependencies = [
|
|
72
72
|
"fs2",
|
|
73
73
|
"serde",
|
|
@@ -76,7 +76,7 @@ dependencies = [
|
|
|
76
76
|
|
|
77
77
|
[[package]]
|
|
78
78
|
name = "omx-sparkshell"
|
|
79
|
-
version = "0.21.
|
|
79
|
+
version = "0.21.35"
|
|
80
80
|
dependencies = [
|
|
81
81
|
"omx-mux",
|
|
82
82
|
]
|
package/Cargo.toml
CHANGED
|
@@ -5813,6 +5813,44 @@ process.on('SIGTERM', () => {});
|
|
|
5813
5813
|
await rm(cwd, { recursive: true, force: true });
|
|
5814
5814
|
}
|
|
5815
5815
|
});
|
|
5816
|
+
it('shutdownTeam clears terminated prompt-worker PIDs before aborting on a partial teardown failure', async () => {
|
|
5817
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-prompt-partial-'));
|
|
5818
|
+
const binDir = join(cwd, 'bin');
|
|
5819
|
+
const fakeCodexPath = join(binDir, 'codex');
|
|
5820
|
+
const originalProcessKill = process.kill;
|
|
5821
|
+
let runtime = null;
|
|
5822
|
+
await mkdir(binDir, { recursive: true });
|
|
5823
|
+
await writeFakePromptWorkerBinary(fakeCodexPath, `
|
|
5824
|
+
process.stdin.resume();
|
|
5825
|
+
setInterval(() => {}, 1000);
|
|
5826
|
+
`);
|
|
5827
|
+
try {
|
|
5828
|
+
runtime = await withPromptModeCodexEnv(binDir, {}, () => withoutTeamWorkerEnv(() => startTeam('team-prompt-partial', 'partial prompt teardown test', 'executor', 2, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)));
|
|
5829
|
+
const stuckPid = runtime.config.workers[0]?.pid ?? 0;
|
|
5830
|
+
const stoppedPid = runtime.config.workers[1]?.pid ?? 0;
|
|
5831
|
+
assert.ok(stuckPid > 0 && stoppedPid > 0);
|
|
5832
|
+
process.kill = ((pid, signal) => {
|
|
5833
|
+
if ((pid === -stuckPid || pid === stuckPid) && signal === 0) {
|
|
5834
|
+
const error = new Error('permission denied');
|
|
5835
|
+
error.code = 'EPERM';
|
|
5836
|
+
throw error;
|
|
5837
|
+
}
|
|
5838
|
+
return originalProcessKill(pid, signal);
|
|
5839
|
+
});
|
|
5840
|
+
await assert.rejects(() => shutdownTeam(runtime.teamName, cwd, { force: true }), /^Error: shutdown_prompt_teardown_failed:worker-1:still_alive_after_sigkill$/);
|
|
5841
|
+
process.kill = originalProcessKill;
|
|
5842
|
+
const retained = await readTeamConfig(runtime.teamName, cwd);
|
|
5843
|
+
assert.ok(retained);
|
|
5844
|
+
assert.equal(retained?.workers[0]?.pid, stuckPid, 'the worker that survived stays recorded for retry');
|
|
5845
|
+
assert.equal(retained?.workers[1]?.pid, undefined, 'a terminated worker PID is never signalled again on retry');
|
|
5846
|
+
}
|
|
5847
|
+
finally {
|
|
5848
|
+
process.kill = originalProcessKill;
|
|
5849
|
+
if (runtime)
|
|
5850
|
+
await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
|
|
5851
|
+
await rm(cwd, { recursive: true, force: true });
|
|
5852
|
+
}
|
|
5853
|
+
});
|
|
5816
5854
|
it('shutdownTeam reaps detached prompt-worker descendants', async () => {
|
|
5817
5855
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-prompt-descendants-'));
|
|
5818
5856
|
const binDir = join(cwd, 'bin');
|
|
@@ -8695,6 +8733,87 @@ esac
|
|
|
8695
8733
|
await rm(cwd, { recursive: true, force: true });
|
|
8696
8734
|
}
|
|
8697
8735
|
});
|
|
8736
|
+
it('shutdownTeam persists killed worker panes before aborting on a partial pane-kill failure', async () => {
|
|
8737
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-shutdown-partial-kill-'));
|
|
8738
|
+
const teamName = 'team-shutdown-partial-kill';
|
|
8739
|
+
try {
|
|
8740
|
+
await withMockTmuxFixture({
|
|
8741
|
+
dirPrefix: 'omx-runtime-shutdown-partial-kill-bin-',
|
|
8742
|
+
tmuxScript: (tmuxLogPath) => `#!/bin/sh
|
|
8743
|
+
set -eu
|
|
8744
|
+
printf '%s\\n' "$*" >> "${tmuxLogPath}"
|
|
8745
|
+
case "$1" in
|
|
8746
|
+
-V)
|
|
8747
|
+
echo "tmux 3.4"
|
|
8748
|
+
;;
|
|
8749
|
+
list-panes)
|
|
8750
|
+
case "$*" in
|
|
8751
|
+
*"-t leader:0"*)
|
|
8752
|
+
printf '%%10\\tzsh\\tzsh\\n'
|
|
8753
|
+
if [ ! -f "${tmuxLogPath}.killed13" ]; then printf '%%13\\tcodex\\tenv OMX_TEAM_INTERNAL_WORKER=team-shutdown-partial-kill/worker-1 codex\\n'; fi
|
|
8754
|
+
printf '%%14\\tcodex\\tenv OMX_TEAM_INTERNAL_WORKER=team-shutdown-partial-kill/worker-2 codex\\n%%15\\tcodex\\tenv OMX_TEAM_INTERNAL_WORKER=team-shutdown-partial-kill/worker-3 codex\\n'
|
|
8755
|
+
;;
|
|
8756
|
+
*"-a -F #{pane_id}"*)
|
|
8757
|
+
printf '%%10\t0\t2000000010\n'
|
|
8758
|
+
if [ ! -f "${tmuxLogPath}.killed13" ]; then printf '%%13\t0\t2000000013\n'; fi
|
|
8759
|
+
printf '%%14\t0\t2000000014\n%%15\t0\t2000000015\n'
|
|
8760
|
+
;;
|
|
8761
|
+
*)
|
|
8762
|
+
exit 1
|
|
8763
|
+
;;
|
|
8764
|
+
esac
|
|
8765
|
+
;;
|
|
8766
|
+
show-option)
|
|
8767
|
+
printf 'owner-1\\n'
|
|
8768
|
+
;;
|
|
8769
|
+
kill-pane)
|
|
8770
|
+
case "$*" in
|
|
8771
|
+
*"-t %13"*) : > "${tmuxLogPath}.killed13" ;;
|
|
8772
|
+
*) echo "kill pane failed" >&2; exit 1 ;;
|
|
8773
|
+
esac
|
|
8774
|
+
;;
|
|
8775
|
+
*)
|
|
8776
|
+
exit 0
|
|
8777
|
+
;;
|
|
8778
|
+
esac
|
|
8779
|
+
`,
|
|
8780
|
+
}, async ({ tmuxLogPath }) => {
|
|
8781
|
+
await initTeamState(teamName, 'shutdown partial kill test', 'executor', 3, cwd);
|
|
8782
|
+
const config = await readTeamConfig(teamName, cwd);
|
|
8783
|
+
assert.ok(config);
|
|
8784
|
+
if (!config)
|
|
8785
|
+
return;
|
|
8786
|
+
config.tmux_session = 'leader:0';
|
|
8787
|
+
config.leader_pane_id = '%10';
|
|
8788
|
+
config.leader_pane_pid = 2000000010;
|
|
8789
|
+
config.hud_pane_id = null;
|
|
8790
|
+
config.tmux_pane_owner_id = 'owner-1';
|
|
8791
|
+
config.workers[0].pane_id = '%13';
|
|
8792
|
+
config.workers[0].pid = 2000000013;
|
|
8793
|
+
config.workers[1].pane_id = '%14';
|
|
8794
|
+
config.workers[1].pid = 2000000014;
|
|
8795
|
+
config.workers[2].pane_id = '%15';
|
|
8796
|
+
config.workers[2].pid = 2000000015;
|
|
8797
|
+
await saveTeamConfig(config, cwd);
|
|
8798
|
+
await assert.rejects(() => shutdownTeam(teamName, cwd, { force: true }), /shutdown_pane_teardown_failed:%14/);
|
|
8799
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
|
|
8800
|
+
assert.match(tmuxLog, /kill-pane -t %13/);
|
|
8801
|
+
assert.match(tmuxLog, /kill-pane -t %14/);
|
|
8802
|
+
assert.doesNotMatch(tmuxLog, /kill-pane -t %15/, 'teardown stops at the first failed kill');
|
|
8803
|
+
const retained = await readTeamConfig(teamName, cwd);
|
|
8804
|
+
assert.ok(retained);
|
|
8805
|
+
assert.equal(retained?.workers[0]?.pane_id, undefined, 'the killed pane is not re-authorized on retry');
|
|
8806
|
+
assert.equal(retained?.workers[0]?.pid, undefined);
|
|
8807
|
+
assert.equal(retained?.workers[1]?.pane_id, '%14', 'the pane whose kill failed stays authorized for retry');
|
|
8808
|
+
assert.equal(retained?.workers[1]?.pid, 2000000014);
|
|
8809
|
+
assert.equal(retained?.workers[2]?.pane_id, '%15', 'a pane never attempted stays authorized for retry');
|
|
8810
|
+
assert.equal(retained?.workers[2]?.pid, 2000000015);
|
|
8811
|
+
});
|
|
8812
|
+
}
|
|
8813
|
+
finally {
|
|
8814
|
+
await rm(cwd, { recursive: true, force: true });
|
|
8815
|
+
}
|
|
8816
|
+
});
|
|
8698
8817
|
it('shutdownTeam preserves unrelated non-worker panes during shared-session shutdown', async () => {
|
|
8699
8818
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-shutdown-unrelated-pane-'));
|
|
8700
8819
|
const teamName = 'team-shutdown-unrelated-pane';
|