oh-my-codex 0.18.9 → 0.18.11
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/README.md +6 -6
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts +2 -0
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts.map +1 -0
- package/dist/autopilot/__tests__/deep-interview-gate.test.js +215 -0
- package/dist/autopilot/__tests__/deep-interview-gate.test.js.map +1 -0
- package/dist/autopilot/__tests__/ralplan-gate.test.js +148 -0
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/deep-interview-gate.d.ts.map +1 -1
- package/dist/autopilot/deep-interview-gate.js +140 -0
- package/dist/autopilot/deep-interview-gate.js.map +1 -1
- package/dist/catalog/__tests__/schema.test.js +6 -0
- package/dist/catalog/__tests__/schema.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +36 -3
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/codex-feature-probe.test.d.ts +2 -0
- package/dist/cli/__tests__/codex-feature-probe.test.d.ts.map +1 -0
- package/dist/cli/__tests__/codex-feature-probe.test.js +46 -0
- package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-spark-routing.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-spark-routing.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-spark-routing.test.js +79 -0
- package/dist/cli/__tests__/doctor-spark-routing.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js +2 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +47 -1175
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +276 -6
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +19 -5
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/nested-help-routing.test.js +1 -1
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +19 -6
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +6 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-packaging.test.js +45 -2
- package/dist/cli/__tests__/sparkshell-packaging.test.js.map +1 -1
- package/dist/cli/__tests__/team-decompose.test.js +10 -5
- package/dist/cli/__tests__/team-decompose.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +45 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +75 -0
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +25 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/codex-feature-probe.d.ts +5 -2
- package/dist/cli/codex-feature-probe.d.ts.map +1 -1
- package/dist/cli/codex-feature-probe.js +25 -9
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/doctor.d.ts +17 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +121 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.d.ts +2 -21
- package/dist/cli/explore.d.ts.map +1 -1
- package/dist/cli/explore.js +25 -624
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +34 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +166 -89
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +9 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts +4 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +43 -4
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +29 -0
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +8 -10
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +15 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +16 -0
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/explore-routing.test.js +5 -8
- package/dist/hooks/__tests__/explore-routing.test.js.map +1 -1
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +6 -6
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.js +14 -5
- package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +2 -1
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/explore-routing.d.ts +1 -1
- package/dist/hooks/explore-routing.d.ts.map +1 -1
- package/dist/hooks/explore-routing.js +3 -8
- package/dist/hooks/explore-routing.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +112 -1
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner-stdin.d.ts +2 -0
- package/dist/hooks/extensibility/plugin-runner-stdin.d.ts.map +1 -0
- package/dist/hooks/extensibility/plugin-runner-stdin.js +16 -0
- package/dist/hooks/extensibility/plugin-runner-stdin.js.map +1 -0
- package/dist/hooks/extensibility/plugin-runner.js +2 -4
- package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +23 -2
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +367 -1
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +118 -7
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/constants.d.ts +10 -0
- package/dist/hud/constants.d.ts.map +1 -1
- package/dist/hud/constants.js +19 -0
- package/dist/hud/constants.js.map +1 -1
- package/dist/hud/index.d.ts +6 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +12 -3
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.d.ts +10 -2
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +78 -30
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/tmux.d.ts +14 -1
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +129 -15
- package/dist/hud/tmux.js.map +1 -1
- package/dist/mcp/wiki-server.d.ts +3 -3
- package/dist/ralplan/consensus-gate.js +9 -1
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +170 -17
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/run-test-files.test.js +115 -1
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +74 -11
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +54 -21
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/run-test-files.js +218 -160
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +463 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/team/__tests__/delivery-log.test.js +18 -0
- package/dist/team/__tests__/delivery-log.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +48 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +107 -0
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js +14 -2
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js +1 -0
- package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +54 -1
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/delivery-log.d.ts +1 -1
- package/dist/team/delivery-log.d.ts.map +1 -1
- package/dist/team/delivery-log.js.map +1 -1
- package/dist/team/repo-aware-decomposition.d.ts +4 -0
- package/dist/team/repo-aware-decomposition.d.ts.map +1 -1
- package/dist/team/repo-aware-decomposition.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +78 -9
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +16 -5
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/ultragoal-context.d.ts +12 -0
- package/dist/team/ultragoal-context.d.ts.map +1 -1
- package/dist/team/ultragoal-context.js +32 -8
- package/dist/team/ultragoal-context.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +23 -0
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +4 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/toml.d.ts +4 -0
- package/dist/utils/toml.d.ts.map +1 -0
- package/dist/utils/toml.js +75 -0
- package/dist/utils/toml.js.map +1 -0
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +3 -0
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +34 -0
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +32 -17
- package/skills/autopilot/SKILL.md +3 -0
- package/skills/deep-interview/SKILL.md +34 -0
- package/skills/ultrawork/SKILL.md +32 -17
- package/src/scripts/__tests__/codex-native-hook.test.ts +218 -28
- package/src/scripts/__tests__/run-test-files.test.ts +138 -2
- package/src/scripts/codex-native-hook.ts +80 -10
- package/src/scripts/notify-hook/team-worker-stop.ts +58 -18
- package/src/scripts/run-test-files.ts +229 -150
- package/templates/AGENTS.md +39 -199
- package/templates/catalog-manifest.json +7 -0
|
@@ -309,13 +309,52 @@ describe("codex native hook dispatch", () => {
|
|
|
309
309
|
it("does not treat a different module url as the main module", () => {
|
|
310
310
|
assert.equal(isCodexNativeHookMainModule(pathToFileURL("/tmp/omx native/other-script.js").href, "/tmp/omx native/codex-native-hook.js"), false);
|
|
311
311
|
});
|
|
312
|
-
it("emits schema-safe JSON
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
312
|
+
it("emits Stop-schema-safe block JSON when unidentifiable malformed stdin has native Stop runtime surface", async () => {
|
|
313
|
+
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-cli-malformed-stop-surface-"));
|
|
314
|
+
try {
|
|
315
|
+
await mkdir(join(cwd, ".omx"), { recursive: true });
|
|
316
|
+
const result = spawnSync(process.execPath, [nativeHookScriptPath()], {
|
|
317
|
+
cwd,
|
|
318
|
+
input: "{",
|
|
319
|
+
encoding: "utf-8",
|
|
320
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
321
|
+
});
|
|
322
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
323
|
+
assert.equal(result.stderr, "");
|
|
324
|
+
const output = parseSingleJsonStdout(result.stdout);
|
|
325
|
+
assert.equal(output.decision, "block");
|
|
326
|
+
assert.equal(output.continue, undefined);
|
|
327
|
+
assert.equal(output.reason, "OMX native hook received malformed JSON input. Preserve runtime state, inspect the emitting hook payload yourself, and retry with valid JSON.");
|
|
328
|
+
assert.equal(output.stopReason, "native_hook_stdin_parse_error");
|
|
329
|
+
assert.equal(output.hookSpecificOutput, undefined);
|
|
330
|
+
assert.match(String(output.systemMessage ?? ""), /stdin JSON parsing failed inside codex-native-hook:/);
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
await rm(cwd, { recursive: true, force: true });
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
it("preserves non-Stop fail-closed JSON when malformed stdin identifies a non-Stop hook", async () => {
|
|
337
|
+
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-cli-malformed-nonstop-"));
|
|
338
|
+
try {
|
|
339
|
+
await mkdir(join(cwd, ".omx"), { recursive: true });
|
|
340
|
+
const result = spawnSync(process.execPath, [nativeHookScriptPath()], {
|
|
341
|
+
cwd,
|
|
342
|
+
input: '{hook_event_name:"PreToolUse",',
|
|
343
|
+
encoding: "utf-8",
|
|
344
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
345
|
+
});
|
|
346
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
347
|
+
assert.equal(result.stderr, "");
|
|
348
|
+
const output = parseSingleJsonStdout(result.stdout);
|
|
349
|
+
assert.equal(output.continue, false);
|
|
350
|
+
assert.equal(output.decision, undefined);
|
|
351
|
+
assert.equal(output.stopReason, "native_hook_stdin_parse_error");
|
|
352
|
+
assert.equal(output.hookSpecificOutput, undefined);
|
|
353
|
+
assert.match(String(output.systemMessage ?? ""), /stdin JSON parsing failed inside codex-native-hook:/);
|
|
354
|
+
}
|
|
355
|
+
finally {
|
|
356
|
+
await rm(cwd, { recursive: true, force: true });
|
|
357
|
+
}
|
|
319
358
|
});
|
|
320
359
|
it("redacts unterminated prompt-like malformed stdin fields", async () => {
|
|
321
360
|
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-cli-malformed-unterminated-"));
|
|
@@ -4194,7 +4233,7 @@ case "$1" in
|
|
|
4194
4233
|
printf '%%1\\tcodex\\tcodex\\n'
|
|
4195
4234
|
;;
|
|
4196
4235
|
display-message)
|
|
4197
|
-
printf '
|
|
4236
|
+
printf '200\\t60\\n'
|
|
4198
4237
|
;;
|
|
4199
4238
|
split-window)
|
|
4200
4239
|
printf '%%9\\n'
|
|
@@ -4316,7 +4355,7 @@ case "$1" in
|
|
|
4316
4355
|
printf '%%2\tnode\texec env OMX_TMUX_HUD_OWNER='"'"'1'"'"' ${OMX_TMUX_HUD_LEADER_PANE_ENV}='"'"'%%1'"'"' /node /omx.js hud --watch\n'
|
|
4317
4356
|
;;
|
|
4318
4357
|
display-message)
|
|
4319
|
-
printf '
|
|
4358
|
+
printf '200\t60\n'
|
|
4320
4359
|
;;
|
|
4321
4360
|
resize-pane)
|
|
4322
4361
|
;;
|
|
@@ -4876,6 +4915,66 @@ exit 0
|
|
|
4876
4915
|
await rm(cwd, { recursive: true, force: true });
|
|
4877
4916
|
}
|
|
4878
4917
|
});
|
|
4918
|
+
it("allows null-device fd redirects while deep-interview blocks real Bash writes", async () => {
|
|
4919
|
+
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-pretool-deep-interview-null-redirect-"));
|
|
4920
|
+
try {
|
|
4921
|
+
const stateDir = join(cwd, ".omx", "state");
|
|
4922
|
+
const sessionDir = join(stateDir, "sessions", "sess-di-null-redirect");
|
|
4923
|
+
await mkdir(sessionDir, { recursive: true });
|
|
4924
|
+
await writeJson(join(stateDir, "session.json"), { session_id: "sess-di-null-redirect", cwd });
|
|
4925
|
+
await writeJson(join(sessionDir, "skill-active-state.json"), {
|
|
4926
|
+
version: 1,
|
|
4927
|
+
active: true,
|
|
4928
|
+
skill: "deep-interview",
|
|
4929
|
+
phase: "planning",
|
|
4930
|
+
session_id: "sess-di-null-redirect",
|
|
4931
|
+
active_skills: [{ skill: "deep-interview", phase: "planning", active: true, session_id: "sess-di-null-redirect" }],
|
|
4932
|
+
});
|
|
4933
|
+
await writeJson(join(sessionDir, "deep-interview-state.json"), {
|
|
4934
|
+
active: true,
|
|
4935
|
+
mode: "deep-interview",
|
|
4936
|
+
current_phase: "intent-first",
|
|
4937
|
+
session_id: "sess-di-null-redirect",
|
|
4938
|
+
});
|
|
4939
|
+
const allowedCommands = [
|
|
4940
|
+
"find application -type d -name 'bug-tracking*' 2>/dev/null | head -20",
|
|
4941
|
+
"find application -type d -name 'bug-tracking*' 2> /dev/null | head -20",
|
|
4942
|
+
"find application -type d -name 'bug-tracking*' 2>NUL | head -20",
|
|
4943
|
+
"find application -type d -name 'bug-tracking*' 1>/dev/null",
|
|
4944
|
+
"find application -type d -name 'bug-tracking*' &>/dev/null",
|
|
4945
|
+
];
|
|
4946
|
+
for (const [index, command] of allowedCommands.entries()) {
|
|
4947
|
+
const result = await dispatchCodexNativeHook({
|
|
4948
|
+
hook_event_name: "PreToolUse",
|
|
4949
|
+
cwd,
|
|
4950
|
+
session_id: "sess-di-null-redirect",
|
|
4951
|
+
tool_name: "Bash",
|
|
4952
|
+
tool_use_id: `tool-di-null-redirect-${index}`,
|
|
4953
|
+
tool_input: { command },
|
|
4954
|
+
}, { cwd });
|
|
4955
|
+
assert.equal(result.outputJson, null, command);
|
|
4956
|
+
}
|
|
4957
|
+
const blockedCommands = [
|
|
4958
|
+
"find application -type d -name 'bug-tracking*' 2>errors.log | head -20",
|
|
4959
|
+
"find application -type d -name 'bug-tracking*' > /tmp/bug-tracking.txt",
|
|
4960
|
+
"find application -type d -name 'bug-tracking*' | tee /dev/null",
|
|
4961
|
+
];
|
|
4962
|
+
for (const [index, command] of blockedCommands.entries()) {
|
|
4963
|
+
const result = await dispatchCodexNativeHook({
|
|
4964
|
+
hook_event_name: "PreToolUse",
|
|
4965
|
+
cwd,
|
|
4966
|
+
session_id: "sess-di-null-redirect",
|
|
4967
|
+
tool_name: "Bash",
|
|
4968
|
+
tool_use_id: `tool-di-real-redirect-${index}`,
|
|
4969
|
+
tool_input: { command },
|
|
4970
|
+
}, { cwd });
|
|
4971
|
+
assert.equal(result.outputJson?.decision, "block", command);
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
finally {
|
|
4975
|
+
await rm(cwd, { recursive: true, force: true });
|
|
4976
|
+
}
|
|
4977
|
+
});
|
|
4879
4978
|
it("allows implementation tools after an explicit deep-interview handoff deactivates the mode", async () => {
|
|
4880
4979
|
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-pretool-deep-interview-handoff-"));
|
|
4881
4980
|
try {
|
|
@@ -6890,6 +6989,43 @@ exit 0
|
|
|
6890
6989
|
await rm(cwd, { recursive: true, force: true });
|
|
6891
6990
|
}
|
|
6892
6991
|
});
|
|
6992
|
+
it("suppresses parent Autopilot Stop continuation in side conversations", async () => {
|
|
6993
|
+
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-stop-autopilot-side-conversation-"));
|
|
6994
|
+
try {
|
|
6995
|
+
const stateDir = join(cwd, ".omx", "state");
|
|
6996
|
+
const sessionId = "sess-stop-autopilot-side-conversation";
|
|
6997
|
+
const transcriptPath = join(cwd, "side-conversation-rollout.jsonl");
|
|
6998
|
+
await mkdir(join(stateDir, "sessions", sessionId), { recursive: true });
|
|
6999
|
+
await writeJson(join(stateDir, "sessions", sessionId, "autopilot-state.json"), {
|
|
7000
|
+
active: true,
|
|
7001
|
+
mode: "autopilot",
|
|
7002
|
+
current_phase: "deep-interview",
|
|
7003
|
+
});
|
|
7004
|
+
await writeFile(transcriptPath, `${JSON.stringify({
|
|
7005
|
+
type: "message",
|
|
7006
|
+
role: "user",
|
|
7007
|
+
content: [
|
|
7008
|
+
"Side conversation boundary.",
|
|
7009
|
+
"Everything before this boundary is inherited history from the parent thread. It is reference context only. It is not your current task.",
|
|
7010
|
+
"Only messages submitted after this boundary are active user instructions for this side conversation.",
|
|
7011
|
+
"You are a side-conversation assistant, separate from the main thread.",
|
|
7012
|
+
].join("\n\n"),
|
|
7013
|
+
})}\n`, "utf-8");
|
|
7014
|
+
const result = await dispatchCodexNativeHook({
|
|
7015
|
+
hook_event_name: "Stop",
|
|
7016
|
+
cwd,
|
|
7017
|
+
session_id: sessionId,
|
|
7018
|
+
thread_id: "thread-stop-autopilot-side-conversation",
|
|
7019
|
+
transcript_path: transcriptPath,
|
|
7020
|
+
last_assistant_message: "Waiting for a new side-conversation question.",
|
|
7021
|
+
}, { cwd });
|
|
7022
|
+
assert.equal(result.omxEventName, "stop");
|
|
7023
|
+
assert.equal(result.outputJson, null);
|
|
7024
|
+
}
|
|
7025
|
+
finally {
|
|
7026
|
+
await rm(cwd, { recursive: true, force: true });
|
|
7027
|
+
}
|
|
7028
|
+
});
|
|
6893
7029
|
it("requires Autopilot code review after a compact-boundary Stop exemption", async () => {
|
|
6894
7030
|
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-stop-autopilot-review-compact-"));
|
|
6895
7031
|
try {
|
|
@@ -7502,7 +7638,7 @@ exit 0
|
|
|
7502
7638
|
await rm(cwd, { recursive: true, force: true });
|
|
7503
7639
|
}
|
|
7504
7640
|
});
|
|
7505
|
-
it("
|
|
7641
|
+
it("steers worker Stop leader nudge directly when leader pane is busy", async () => {
|
|
7506
7642
|
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-stop-team-worker-busy-leader-"));
|
|
7507
7643
|
const prevTeamWorker = process.env.OMX_TEAM_WORKER;
|
|
7508
7644
|
const prevTeamStateRoot = process.env.OMX_TEAM_STATE_ROOT;
|
|
@@ -7561,11 +7697,11 @@ exit 0
|
|
|
7561
7697
|
assert.equal(result.outputJson, null);
|
|
7562
7698
|
const tmuxLog = await readFile(tmuxLogPath, "utf-8");
|
|
7563
7699
|
assert.match(tmuxLog, /send-keys -t %42 -l \[OMX\] worker-1 native Stop allowed/);
|
|
7564
|
-
assert.
|
|
7565
|
-
|
|
7566
|
-
assert.
|
|
7700
|
+
assert.doesNotMatch(tmuxLog, /send-keys -t %42 Tab/);
|
|
7701
|
+
const submits = tmuxLog.match(/send-keys -t %42 C-m/g) || [];
|
|
7702
|
+
assert.equal(submits.length, 2, "busy worker-stop nudge should submit directly as steering, not queue via Tab");
|
|
7567
7703
|
const nudgeState = JSON.parse(await readFile(join(workerDir, "worker-stop-nudge.json"), "utf-8"));
|
|
7568
|
-
assert.equal(nudgeState.delivery, "
|
|
7704
|
+
assert.equal(nudgeState.delivery, "steered");
|
|
7569
7705
|
}
|
|
7570
7706
|
finally {
|
|
7571
7707
|
if (typeof prevTeamWorker === "string")
|
|
@@ -7705,6 +7841,14 @@ exit 0
|
|
|
7705
7841
|
});
|
|
7706
7842
|
assert.equal(shutdownResult.result, "team_state_gone_or_shutdown");
|
|
7707
7843
|
assert.equal(existsSync(join(stateDir, "team", "shutdown-team", "worker-stop-nudge.json")), false);
|
|
7844
|
+
const deliveryLogPath = join(logsDir, `team-delivery-${new Date().toISOString().split("T")[0]}.jsonl`);
|
|
7845
|
+
const deliveryEvents = (await readFile(deliveryLogPath, "utf-8"))
|
|
7846
|
+
.trim()
|
|
7847
|
+
.split("\n")
|
|
7848
|
+
.map((line) => JSON.parse(line));
|
|
7849
|
+
const suppressedEvents = deliveryEvents.filter((event) => event.reason === "team_state_gone_or_shutdown");
|
|
7850
|
+
assert.equal(suppressedEvents.length, 2, "late closed-team Stop nudges should be diagnostics, not queued prompts");
|
|
7851
|
+
assert.equal(suppressedEvents.every((event) => event.result === "suppressed" && event.transport === "none"), true);
|
|
7708
7852
|
}
|
|
7709
7853
|
finally {
|
|
7710
7854
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -7739,13 +7883,13 @@ exit 0
|
|
|
7739
7883
|
logsDir,
|
|
7740
7884
|
workerContext: { teamName, workerName: "worker-2" },
|
|
7741
7885
|
});
|
|
7742
|
-
assert.equal(result.result, "
|
|
7886
|
+
assert.equal(result.result, "steered");
|
|
7743
7887
|
const tmuxLog = await readFile(tmuxLogPath, "utf-8");
|
|
7744
7888
|
assert.match(tmuxLog, /send-keys -t %42 -l \[OMX\] worker-2 native Stop allowed/);
|
|
7745
|
-
assert.
|
|
7889
|
+
assert.doesNotMatch(tmuxLog, /send-keys -t %42 Tab/);
|
|
7746
7890
|
const teamNudgeState = JSON.parse(await readFile(join(teamDir, "worker-stop-nudge.json"), "utf-8"));
|
|
7747
7891
|
assert.equal(teamNudgeState.worker, "worker-2");
|
|
7748
|
-
assert.equal(teamNudgeState.delivery, "
|
|
7892
|
+
assert.equal(teamNudgeState.delivery, "steered");
|
|
7749
7893
|
}
|
|
7750
7894
|
finally {
|
|
7751
7895
|
if (typeof prevPath === "string")
|
|
@@ -7875,6 +8019,15 @@ exit 0
|
|
|
7875
8019
|
assert.equal(existsSync(teamDir), false, "deferred worker Stop recording must not recreate removed team state");
|
|
7876
8020
|
const tmuxLog = await readFile(tmuxLogPath, "utf-8");
|
|
7877
8021
|
assert.doesNotMatch(tmuxLog, /send-keys -t %42 -l \[OMX\] worker-1 native Stop allowed/);
|
|
8022
|
+
const deliveryLogPath = join(logsDir, `team-delivery-${new Date().toISOString().split("T")[0]}.jsonl`);
|
|
8023
|
+
const deliveryEvents = (await readFile(deliveryLogPath, "utf-8"))
|
|
8024
|
+
.trim()
|
|
8025
|
+
.split("\n")
|
|
8026
|
+
.map((line) => JSON.parse(line));
|
|
8027
|
+
assert.equal(deliveryEvents.some((event) => event.team === teamName
|
|
8028
|
+
&& event.result === "suppressed"
|
|
8029
|
+
&& event.transport === "none"
|
|
8030
|
+
&& event.reason === "team_state_gone_or_shutdown"), true, "teardown-race worker Stop nudges should be diagnostic suppression events, not queued prompts");
|
|
7878
8031
|
}
|
|
7879
8032
|
finally {
|
|
7880
8033
|
if (typeof prevPath === "string")
|