oh-my-codex 0.11.13 → 0.12.1
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 +34 -17
- package/crates/omx-runtime/src/main.rs +6 -2
- package/dist/agents/native-config.js +1 -1
- package/dist/agents/native-config.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-guided.test.js +74 -2
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
- package/dist/cli/__tests__/cleanup.test.js +37 -30
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js +3 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +276 -5
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +95 -1
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +49 -9
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +9 -0
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +136 -11
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +10 -0
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +1 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/autoresearch-guided.d.ts.map +1 -1
- package/dist/cli/autoresearch-guided.js +2 -1
- package/dist/cli/autoresearch-guided.js.map +1 -1
- package/dist/cli/autoresearch.d.ts.map +1 -1
- package/dist/cli/autoresearch.js +2 -1
- package/dist/cli/autoresearch.js.map +1 -1
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +10 -5
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/index.d.ts +21 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +298 -36
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/omx.js +2 -0
- package/dist/cli/omx.js.map +1 -1
- package/dist/cli/setup.d.ts +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +41 -7
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +16 -557
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +34 -9
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +79 -2
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +2 -0
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +11 -0
- package/dist/config/codex-hooks.d.ts.map +1 -0
- package/dist/config/codex-hooks.js +50 -0
- package/dist/config/codex-hooks.js.map +1 -0
- package/dist/config/generator.d.ts +5 -3
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +24 -14
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +20 -0
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +132 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +292 -4
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +86 -0
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +40 -0
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +54 -0
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js +31 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +51 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +136 -0
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +120 -0
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +145 -20
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +116 -0
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +86 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +1 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/runtime.test.js +49 -0
- package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -1
- package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
- package/dist/hooks/extensibility/runtime.js +10 -0
- package/dist/hooks/extensibility/runtime.js.map +1 -1
- package/dist/hooks/extensibility/types.d.ts +1 -1
- package/dist/hooks/extensibility/types.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +2 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +76 -4
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +12 -8
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +5 -1
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +10 -6
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +6 -1
- package/dist/hud/index.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +0 -3
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/code-intel-server.test.js +27 -1
- package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +0 -5
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +1 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +0 -1
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/code-intel-server.d.ts +20 -0
- package/dist/mcp/code-intel-server.d.ts.map +1 -1
- package/dist/mcp/code-intel-server.js +6 -5
- package/dist/mcp/code-intel-server.js.map +1 -1
- package/dist/notifications/__tests__/idle-cooldown.test.js +24 -1
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/notifications/__tests__/reply-listener.test.js +20 -1
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/__tests__/tmux.test.js +41 -0
- package/dist/notifications/__tests__/tmux.test.js.map +1 -1
- package/dist/notifications/idle-cooldown.d.ts +13 -0
- package/dist/notifications/idle-cooldown.d.ts.map +1 -1
- package/dist/notifications/idle-cooldown.js +50 -16
- package/dist/notifications/idle-cooldown.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +2 -0
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +4 -0
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.d.ts +2 -0
- package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/codex-native-hook.test.js +1050 -0
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts +22 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -0
- package/dist/scripts/codex-native-hook.js +792 -0
- package/dist/scripts/codex-native-hook.js.map +1 -0
- package/dist/scripts/codex-native-pre-post.d.ts +26 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -0
- package/dist/scripts/codex-native-pre-post.js +118 -0
- package/dist/scripts/codex-native-pre-post.js.map +1 -0
- package/dist/scripts/notify-fallback-watcher.js +322 -21
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +5 -6
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/log.d.ts +2 -2
- package/dist/scripts/notify-hook/log.d.ts.map +1 -1
- package/dist/scripts/notify-hook/log.js +10 -2
- package/dist/scripts/notify-hook/log.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +2 -0
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/orchestration-intent.d.ts +18 -0
- package/dist/scripts/notify-hook/orchestration-intent.d.ts.map +1 -0
- package/dist/scripts/notify-hook/orchestration-intent.js +72 -0
- package/dist/scripts/notify-hook/orchestration-intent.js.map +1 -0
- package/dist/scripts/notify-hook/process-runner.js.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +7 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts +15 -6
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +125 -6
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +3 -2
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +165 -37
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +4 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +33 -44
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +68 -5
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/utils.d.ts +1 -1
- package/dist/scripts/notify-hook/utils.d.ts.map +1 -1
- package/dist/scripts/notify-hook/utils.js.map +1 -1
- package/dist/scripts/notify-hook.js +55 -32
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +344 -18
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +2 -0
- package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +1 -0
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +671 -0
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -0
- package/dist/team/__tests__/mcp-comm.test.js +5 -0
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +543 -15
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +133 -8
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/team-ops-contract.test.js +4 -0
- package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +160 -0
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +19 -1
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +95 -23
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/contracts.d.ts +11 -1
- package/dist/team/contracts.d.ts.map +1 -1
- package/dist/team/contracts.js +29 -0
- package/dist/team/contracts.js.map +1 -1
- package/dist/team/delivery-log.d.ts +14 -0
- package/dist/team/delivery-log.d.ts.map +1 -0
- package/dist/team/delivery-log.js +35 -0
- package/dist/team/delivery-log.js.map +1 -0
- package/dist/team/idle-nudge.d.ts +2 -2
- package/dist/team/idle-nudge.js +2 -2
- package/dist/team/mcp-comm.d.ts +4 -0
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +84 -1
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/pane-status.d.ts +149 -0
- package/dist/team/pane-status.d.ts.map +1 -0
- package/dist/team/pane-status.js +558 -0
- package/dist/team/pane-status.js.map +1 -0
- package/dist/team/reminder-intents.d.ts +11 -0
- package/dist/team/reminder-intents.d.ts.map +1 -0
- package/dist/team/reminder-intents.js +40 -0
- package/dist/team/reminder-intents.js.map +1 -0
- package/dist/team/runtime-cli.d.ts +1 -1
- package/dist/team/runtime-cli.js +2 -2
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts +2 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +409 -191
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +6 -5
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/dispatch.d.ts +4 -1
- package/dist/team/state/dispatch.d.ts.map +1 -1
- package/dist/team/state/dispatch.js +59 -18
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/mailbox.d.ts.map +1 -1
- package/dist/team/state/mailbox.js +45 -2
- package/dist/team/state/mailbox.js.map +1 -1
- package/dist/team/state/monitor.d.ts +2 -1
- package/dist/team/state/monitor.d.ts.map +1 -1
- package/dist/team/state/monitor.js +30 -1
- package/dist/team/state/monitor.js.map +1 -1
- package/dist/team/state/types.d.ts +5 -2
- package/dist/team/state/types.d.ts.map +1 -1
- package/dist/team/state/types.js.map +1 -1
- package/dist/team/state.d.ts +30 -3
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +170 -2
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-ops.d.ts +5 -1
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +4 -0
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/tmux-session.d.ts +2 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +19 -3
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +4 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +33 -6
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +63 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +50 -4
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/paths.d.ts +12 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +44 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +13 -5
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js +10 -1
- package/dist/utils/sleep.js.map +1 -1
- package/package.json +1 -1
- package/prompts/analyst.md +2 -2
- package/prompts/api-reviewer.md +2 -2
- package/prompts/architect.md +2 -2
- package/prompts/build-fixer.md +2 -2
- package/prompts/code-reviewer.md +2 -2
- package/prompts/code-simplifier.md +1 -1
- package/prompts/critic.md +2 -2
- package/prompts/debugger.md +3 -2
- package/prompts/dependency-expert.md +2 -2
- package/prompts/designer.md +2 -2
- package/prompts/executor.md +3 -2
- package/prompts/explore.md +2 -2
- package/prompts/git-master.md +2 -2
- package/prompts/information-architect.md +15 -102
- package/prompts/performance-reviewer.md +2 -2
- package/prompts/planner.md +3 -2
- package/prompts/product-analyst.md +2 -2
- package/prompts/product-manager.md +2 -2
- package/prompts/qa-tester.md +2 -2
- package/prompts/quality-reviewer.md +2 -2
- package/prompts/quality-strategist.md +2 -2
- package/prompts/researcher.md +2 -2
- package/prompts/security-reviewer.md +2 -2
- package/prompts/sisyphus-lite.md +2 -2
- package/prompts/style-reviewer.md +2 -2
- package/prompts/team-executor.md +2 -2
- package/prompts/test-engineer.md +2 -2
- package/prompts/ux-researcher.md +2 -2
- package/prompts/verifier.md +3 -2
- package/prompts/vision.md +2 -2
- package/prompts/writer.md +2 -2
- package/skills/team/SKILL.md +18 -33
- package/src/scripts/__tests__/codex-native-hook.test.ts +1346 -0
- package/src/scripts/codex-native-hook.ts +983 -0
- package/src/scripts/codex-native-pre-post.ts +161 -0
- package/src/scripts/notify-fallback-watcher.ts +378 -29
- package/src/scripts/notify-hook/auto-nudge.ts +5 -10
- package/src/scripts/notify-hook/log.ts +18 -4
- package/src/scripts/notify-hook/managed-tmux.ts +1 -0
- package/src/scripts/notify-hook/orchestration-intent.ts +82 -0
- package/src/scripts/notify-hook/process-runner.ts +4 -4
- package/src/scripts/notify-hook/ralph-session-resume.ts +9 -0
- package/src/scripts/notify-hook/team-dispatch.ts +134 -6
- package/src/scripts/notify-hook/team-leader-nudge.ts +183 -37
- package/src/scripts/notify-hook/team-tmux-guard.ts +35 -43
- package/src/scripts/notify-hook/team-worker.ts +73 -4
- package/src/scripts/notify-hook/utils.ts +1 -1
- package/src/scripts/notify-hook.ts +64 -32
- package/templates/AGENTS.md +21 -11
- package/README.de.md +0 -263
- package/README.el.md +0 -223
- package/README.es.md +0 -263
- package/README.fr.md +0 -263
- package/README.it.md +0 -263
- package/README.ja.md +0 -264
- package/README.ko.md +0 -264
- package/README.pl.md +0 -216
- package/README.pt.md +0 -263
- package/README.ru.md +0 -263
- package/README.tr.md +0 -263
- package/README.vi.md +0 -223
- package/README.zh-TW.md +0 -293
- package/README.zh.md +0 -264
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts +0 -2
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/team-server-cleanup.test.js +0 -219
- package/dist/mcp/__tests__/team-server-cleanup.test.js.map +0 -1
- package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts +0 -2
- package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/team-server-runtime-deps.test.js +0 -13
- package/dist/mcp/__tests__/team-server-runtime-deps.test.js.map +0 -1
- package/dist/mcp/__tests__/team-server-wait.test.d.ts +0 -2
- package/dist/mcp/__tests__/team-server-wait.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/team-server-wait.test.js +0 -155
- package/dist/mcp/__tests__/team-server-wait.test.js.map +0 -1
- package/dist/mcp/team-server.d.ts +0 -24
- package/dist/mcp/team-server.d.ts.map +0 -1
- package/dist/mcp/team-server.js +0 -482
- package/dist/mcp/team-server.js.map +0 -1
|
@@ -22,6 +22,14 @@ async function readLines(path) {
|
|
|
22
22
|
const content = await readFile(path, 'utf-8').catch(() => '');
|
|
23
23
|
return content.split('\n').map(s => s.trim()).filter(Boolean);
|
|
24
24
|
}
|
|
25
|
+
async function readJsonLines(path) {
|
|
26
|
+
const content = await readFile(path, 'utf-8').catch(() => '');
|
|
27
|
+
return content
|
|
28
|
+
.split('\n')
|
|
29
|
+
.map((line) => line.trim())
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.map((line) => JSON.parse(line));
|
|
32
|
+
}
|
|
25
33
|
async function sleep(ms) {
|
|
26
34
|
await new Promise(resolve => setTimeout(resolve, ms));
|
|
27
35
|
}
|
|
@@ -213,6 +221,60 @@ describe('notify-fallback watcher', () => {
|
|
|
213
221
|
assert.equal(turnLines.length, 1);
|
|
214
222
|
assert.match(turnLines[0], new RegExp(freshTurn));
|
|
215
223
|
assert.doesNotMatch(turnLines[0], new RegExp(staleTurn));
|
|
224
|
+
const fallbackLog = join(wd, '.omx', 'logs', `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
225
|
+
const fallbackEntries = await readJsonLines(fallbackLog);
|
|
226
|
+
assert.deepEqual(fallbackEntries.map((entry) => entry.type), ['fallback_notify']);
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
await rm(wd, { recursive: true, force: true });
|
|
230
|
+
await rm(tempHome, { recursive: true, force: true });
|
|
231
|
+
await rm(rolloutPath, { force: true });
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
it('rotates notify-fallback logs when the size cap is exceeded', async () => {
|
|
235
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-once-rotate-'));
|
|
236
|
+
const tempHome = await mkdtemp(join(tmpdir(), 'omx-fallback-home-'));
|
|
237
|
+
const sid = randomUUID();
|
|
238
|
+
const sessionDir = todaySessionDir(tempHome);
|
|
239
|
+
const rolloutPath = join(sessionDir, `rollout-test-fallback-rotate-${sid}.jsonl`);
|
|
240
|
+
try {
|
|
241
|
+
await mkdir(join(wd, '.omx', 'logs'), { recursive: true });
|
|
242
|
+
await mkdir(join(wd, '.omx', 'state'), { recursive: true });
|
|
243
|
+
await mkdir(sessionDir, { recursive: true });
|
|
244
|
+
const threadId = `thread-${sid}`;
|
|
245
|
+
const turnIds = ['first', 'second', 'third'].map((label) => `turn-${label}-${sid}`);
|
|
246
|
+
const nowIso = new Date(Date.now() + 2_000).toISOString();
|
|
247
|
+
const lines = [
|
|
248
|
+
{
|
|
249
|
+
timestamp: nowIso,
|
|
250
|
+
type: 'session_meta',
|
|
251
|
+
payload: { id: threadId, cwd: wd },
|
|
252
|
+
},
|
|
253
|
+
...turnIds.map((turnId) => ({
|
|
254
|
+
timestamp: nowIso,
|
|
255
|
+
type: 'event_msg',
|
|
256
|
+
payload: {
|
|
257
|
+
type: 'task_complete',
|
|
258
|
+
turn_id: turnId,
|
|
259
|
+
last_agent_message: `message for ${turnId}`,
|
|
260
|
+
},
|
|
261
|
+
})),
|
|
262
|
+
];
|
|
263
|
+
await writeFile(rolloutPath, `${lines.map(v => JSON.stringify(v)).join('\n')}\n`);
|
|
264
|
+
const watcherScript = new URL('../../../dist/scripts/notify-fallback-watcher.js', import.meta.url).pathname;
|
|
265
|
+
const notifyHook = new URL('../../../dist/scripts/notify-hook.js', import.meta.url).pathname;
|
|
266
|
+
const result = spawnSync(process.execPath, [watcherScript, '--once', '--cwd', wd, '--notify-script', notifyHook, '--poll-ms', '50', '--log-max-bytes', '1'], { encoding: 'utf-8', env: buildCleanNotifyEnv({ HOME: tempHome }) });
|
|
267
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
268
|
+
const fallbackLog = join(wd, '.omx', 'logs', `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
269
|
+
const rotatedLog = `${fallbackLog}.1`;
|
|
270
|
+
const currentEntries = await readJsonLines(fallbackLog);
|
|
271
|
+
const rotatedEntries = await readJsonLines(rotatedLog);
|
|
272
|
+
assert.equal(currentEntries.length, 1);
|
|
273
|
+
assert.equal(rotatedEntries.length, 1);
|
|
274
|
+
assert.equal(currentEntries[0]?.turn_id, turnIds[2]);
|
|
275
|
+
assert.equal(rotatedEntries[0]?.turn_id, turnIds[1]);
|
|
276
|
+
assert.deepEqual(currentEntries.map((entry) => entry.type), ['fallback_notify']);
|
|
277
|
+
assert.deepEqual(rotatedEntries.map((entry) => entry.type), ['fallback_notify']);
|
|
216
278
|
}
|
|
217
279
|
finally {
|
|
218
280
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -452,6 +514,70 @@ describe('notify-fallback watcher', () => {
|
|
|
452
514
|
await rm(wd, { recursive: true, force: true });
|
|
453
515
|
}
|
|
454
516
|
});
|
|
517
|
+
it('backs off authority-only nudge ticks when the primary watcher is healthy', async () => {
|
|
518
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-authority-backed-off-'));
|
|
519
|
+
const fakeBinDir = join(wd, 'fake-bin');
|
|
520
|
+
const tmuxLogPath = join(wd, 'tmux.log');
|
|
521
|
+
const codexHome = join(wd, 'codex-home');
|
|
522
|
+
try {
|
|
523
|
+
await mkdir(join(wd, '.omx', 'logs'), { recursive: true });
|
|
524
|
+
await mkdir(join(wd, '.omx', 'state'), { recursive: true });
|
|
525
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
526
|
+
await mkdir(codexHome, { recursive: true });
|
|
527
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
528
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
529
|
+
await writeFile(join(codexHome, '.omx-config.json'), JSON.stringify({
|
|
530
|
+
autoNudge: { enabled: true, delaySec: 0, ttlMs: 30_000 },
|
|
531
|
+
}, null, 2));
|
|
532
|
+
await writeSessionStart(wd, 'sess-managed-fallback');
|
|
533
|
+
await writeFile(join(wd, '.omx', 'state', 'hud-state.json'), JSON.stringify({
|
|
534
|
+
last_turn_at: new Date(Date.now() - 6_000).toISOString(),
|
|
535
|
+
turn_count: 7,
|
|
536
|
+
last_agent_output: 'If you want, I can keep going from here.',
|
|
537
|
+
}, null, 2));
|
|
538
|
+
await writeFile(join(wd, '.omx', 'state', 'notify-fallback.pid'), JSON.stringify({
|
|
539
|
+
pid: process.pid,
|
|
540
|
+
cwd: wd,
|
|
541
|
+
started_at: new Date().toISOString(),
|
|
542
|
+
}, null, 2));
|
|
543
|
+
await writeFile(join(wd, '.omx', 'state', 'notify-fallback-state.json'), JSON.stringify({
|
|
544
|
+
pid: process.pid,
|
|
545
|
+
cwd: wd,
|
|
546
|
+
authority_only: false,
|
|
547
|
+
poll_ms: 250,
|
|
548
|
+
dispatch_drain: { last_tick_at: new Date().toISOString() },
|
|
549
|
+
}, null, 2));
|
|
550
|
+
const watcherScript = new URL('../../../dist/scripts/notify-fallback-watcher.js', import.meta.url).pathname;
|
|
551
|
+
const notifyHook = new URL('../../../dist/scripts/notify-hook.js', import.meta.url).pathname;
|
|
552
|
+
const result = spawnSync(process.execPath, [watcherScript, '--once', '--authority-only', '--cwd', wd, '--notify-script', notifyHook, '--poll-ms', '50'], {
|
|
553
|
+
encoding: 'utf-8',
|
|
554
|
+
env: buildCleanNotifyEnv({
|
|
555
|
+
PATH: `${fakeBinDir}:${process.env.PATH || ''}`,
|
|
556
|
+
CODEX_HOME: codexHome,
|
|
557
|
+
OMX_SESSION_ID: 'sess-managed-fallback',
|
|
558
|
+
TMUX: '1',
|
|
559
|
+
TMUX_PANE: '%42',
|
|
560
|
+
OMX_NOTIFY_FALLBACK_AUTO_NUDGE_STALL_MS: '5000',
|
|
561
|
+
}),
|
|
562
|
+
});
|
|
563
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
564
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8').catch(() => '');
|
|
565
|
+
assert.doesNotMatch(tmuxLog, /send-keys -t %42 -l yes, proceed \[OMX_TMUX_INJECT\]/);
|
|
566
|
+
const watcherState = JSON.parse(await readFile(join(wd, '.omx', 'state', 'notify-fallback-state.json'), 'utf-8'));
|
|
567
|
+
assert.equal(watcherState.pid, process.pid, 'authority backoff should preserve the primary watcher state owner');
|
|
568
|
+
assert.equal(watcherState.authority_only, false, 'authority backoff should not overwrite primary watcher ownership');
|
|
569
|
+
assert.equal(watcherState.authority_backoff?.active, true);
|
|
570
|
+
assert.equal(watcherState.authority_backoff?.reason, 'primary_watcher_healthy');
|
|
571
|
+
assert.equal(watcherState.authority_backoff?.primary_pid, process.pid);
|
|
572
|
+
assert.match(watcherState.dispatch_drain?.last_tick_at ?? '', /^\d{4}-\d{2}-\d{2}T/);
|
|
573
|
+
const logPath = join(wd, '.omx', 'logs', `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
574
|
+
const logContent = await readFile(logPath, 'utf-8').catch(() => '');
|
|
575
|
+
assert.equal(logContent.trim(), '');
|
|
576
|
+
}
|
|
577
|
+
finally {
|
|
578
|
+
await rm(wd, { recursive: true, force: true });
|
|
579
|
+
}
|
|
580
|
+
});
|
|
455
581
|
it('disables fallback watcher nudges when deep-interview state is active', async () => {
|
|
456
582
|
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-deep-interview-suppressed-'));
|
|
457
583
|
const fakeBinDir = join(wd, 'fake-bin');
|
|
@@ -600,7 +726,7 @@ describe('notify-fallback watcher', () => {
|
|
|
600
726
|
});
|
|
601
727
|
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
602
728
|
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
603
|
-
assert.match(tmuxLog, /send-keys -t %42 -l Team dispatch-team: leader stale
|
|
729
|
+
assert.match(tmuxLog, /send-keys -t %42 -l Team dispatch-team: leader stale, \d+ worker pane\(s\) still active\./);
|
|
604
730
|
const watcherStatePath = join(wd, '.omx', 'state', 'notify-fallback-state.json');
|
|
605
731
|
const watcherState = JSON.parse(await readFile(watcherStatePath, 'utf-8'));
|
|
606
732
|
assert.equal(watcherState.poll_ms, 250);
|
|
@@ -614,6 +740,12 @@ describe('notify-fallback watcher', () => {
|
|
|
614
740
|
assert.ok(nudgeEvent, 'expected leader_nudge_tick log event');
|
|
615
741
|
assert.equal(nudgeEvent.leader_only, true);
|
|
616
742
|
assert.equal(nudgeEvent.precomputed_leader_stale, true);
|
|
743
|
+
const deliveryLogPath = join(wd, '.omx', 'logs', `team-delivery-${new Date().toISOString().slice(0, 10)}.jsonl`);
|
|
744
|
+
const deliveryEntries = await readJsonLines(deliveryLogPath);
|
|
745
|
+
assert.ok(deliveryEntries.some((entry) => entry.event === 'nudge_triggered'
|
|
746
|
+
&& entry.source === 'notify_fallback_watcher'
|
|
747
|
+
&& entry.transport === 'send-keys'
|
|
748
|
+
&& entry.result === 'sent'));
|
|
617
749
|
}
|
|
618
750
|
finally {
|
|
619
751
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -673,7 +805,7 @@ describe('notify-fallback watcher', () => {
|
|
|
673
805
|
assert.equal(watcherState.leader_nudge?.run_count, 1);
|
|
674
806
|
assert.equal(watcherState.leader_nudge?.precomputed_leader_stale, false);
|
|
675
807
|
const logPath = join(wd, '.omx', 'logs', `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
676
|
-
const logEntries =
|
|
808
|
+
const logEntries = await readJsonLines(logPath);
|
|
677
809
|
const nudgeEvent = logEntries.find((entry) => entry.type === 'leader_nudge_tick');
|
|
678
810
|
assert.equal(nudgeEvent, undefined);
|
|
679
811
|
}
|
|
@@ -842,7 +974,7 @@ exit 0
|
|
|
842
974
|
});
|
|
843
975
|
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
844
976
|
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
845
|
-
assert.match(tmuxLog, /send-keys -t %42 -l Team dispatch-team: worker panes stalled, no progress 3m
|
|
977
|
+
assert.match(tmuxLog, /send-keys -t %42 -l Team dispatch-team: worker panes stalled, no progress 3m\./);
|
|
846
978
|
assert.doesNotMatch(tmuxLog, /leader stale/);
|
|
847
979
|
const watcherStatePath = join(wd, '.omx', 'state', 'notify-fallback-state.json');
|
|
848
980
|
const watcherState = JSON.parse(await readFile(watcherStatePath, 'utf-8'));
|
|
@@ -1195,7 +1327,7 @@ exit 0
|
|
|
1195
1327
|
assert.equal(watcherState.dispatch_drain?.last_result?.reason, 'worker_context');
|
|
1196
1328
|
assert.equal(watcherState.dispatch_drain?.last_result?.processed, 0);
|
|
1197
1329
|
const logPath = join(wd, '.omx', 'logs', `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
1198
|
-
const logEntries =
|
|
1330
|
+
const logEntries = await readJsonLines(logPath);
|
|
1199
1331
|
const drainEvent = logEntries.find((entry) => entry.type === 'dispatch_drain_tick');
|
|
1200
1332
|
assert.equal(drainEvent, undefined);
|
|
1201
1333
|
}
|
|
@@ -1398,6 +1530,83 @@ exit 0
|
|
|
1398
1530
|
await rm(wd, { recursive: true, force: true });
|
|
1399
1531
|
}
|
|
1400
1532
|
});
|
|
1533
|
+
it('suppresses Ralph continue steer while tracked native subagents are still active', async () => {
|
|
1534
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-ralph-subagents-active-'));
|
|
1535
|
+
const fakeBinDir = join(wd, 'fake-bin');
|
|
1536
|
+
const stateDir = join(wd, '.omx', 'state');
|
|
1537
|
+
const tmuxLogPath = join(wd, 'tmux.log');
|
|
1538
|
+
const statePath = join(stateDir, 'notify-fallback-state.json');
|
|
1539
|
+
const omxSessionId = 'sess-current';
|
|
1540
|
+
const codexSessionId = 'codex-session-1';
|
|
1541
|
+
try {
|
|
1542
|
+
await mkdir(join(stateDir, 'sessions', omxSessionId), { recursive: true });
|
|
1543
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
1544
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
1545
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
1546
|
+
await writeSessionStart(wd, omxSessionId);
|
|
1547
|
+
await writeFile(join(stateDir, 'sessions', omxSessionId, 'ralph-state.json'), JSON.stringify({
|
|
1548
|
+
active: true,
|
|
1549
|
+
current_phase: 'executing',
|
|
1550
|
+
tmux_pane_id: '%42',
|
|
1551
|
+
owner_omx_session_id: omxSessionId,
|
|
1552
|
+
owner_codex_session_id: codexSessionId,
|
|
1553
|
+
}, null, 2));
|
|
1554
|
+
await writeFile(join(stateDir, 'hud-state.json'), JSON.stringify({
|
|
1555
|
+
last_progress_at: new Date(Date.now() - 61_000).toISOString(),
|
|
1556
|
+
}, null, 2));
|
|
1557
|
+
await writeFile(statePath, JSON.stringify({
|
|
1558
|
+
ralph_continue_steer: {
|
|
1559
|
+
last_sent_at: new Date(Date.now() - 61_000).toISOString(),
|
|
1560
|
+
},
|
|
1561
|
+
}, null, 2));
|
|
1562
|
+
await writeFile(join(stateDir, 'subagent-tracking.json'), JSON.stringify({
|
|
1563
|
+
schemaVersion: 1,
|
|
1564
|
+
sessions: {
|
|
1565
|
+
[codexSessionId]: {
|
|
1566
|
+
session_id: codexSessionId,
|
|
1567
|
+
leader_thread_id: 'leader-thread',
|
|
1568
|
+
updated_at: new Date(Date.now() - 15_000).toISOString(),
|
|
1569
|
+
threads: {
|
|
1570
|
+
'leader-thread': {
|
|
1571
|
+
thread_id: 'leader-thread',
|
|
1572
|
+
kind: 'leader',
|
|
1573
|
+
first_seen_at: new Date(Date.now() - 30_000).toISOString(),
|
|
1574
|
+
last_seen_at: new Date(Date.now() - 15_000).toISOString(),
|
|
1575
|
+
turn_count: 1,
|
|
1576
|
+
mode: 'ralph',
|
|
1577
|
+
},
|
|
1578
|
+
'sub-thread-1': {
|
|
1579
|
+
thread_id: 'sub-thread-1',
|
|
1580
|
+
kind: 'subagent',
|
|
1581
|
+
first_seen_at: new Date(Date.now() - 30_000).toISOString(),
|
|
1582
|
+
last_seen_at: new Date(Date.now() - 15_000).toISOString(),
|
|
1583
|
+
turn_count: 1,
|
|
1584
|
+
mode: 'ralph',
|
|
1585
|
+
},
|
|
1586
|
+
},
|
|
1587
|
+
},
|
|
1588
|
+
},
|
|
1589
|
+
}, null, 2));
|
|
1590
|
+
const watcherScript = new URL('../../../dist/scripts/notify-fallback-watcher.js', import.meta.url).pathname;
|
|
1591
|
+
const notifyHook = new URL('../../../dist/scripts/notify-hook.js', import.meta.url).pathname;
|
|
1592
|
+
const env = {
|
|
1593
|
+
...buildCleanNotifyEnv(),
|
|
1594
|
+
PATH: `${fakeBinDir}:${process.env.PATH || ''}`,
|
|
1595
|
+
};
|
|
1596
|
+
const run = spawnSync(process.execPath, [watcherScript, '--once', '--cwd', wd, '--notify-script', notifyHook, '--poll-ms', '50'], { encoding: 'utf-8', env });
|
|
1597
|
+
assert.equal(run.status, 0, run.stderr || run.stdout);
|
|
1598
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8').catch(() => '');
|
|
1599
|
+
const sends = tmuxLog.match(/send-keys -t %42 -l Ralph loop active continue \[OMX_TMUX_INJECT\]/g) || [];
|
|
1600
|
+
assert.equal(sends.length, 0, 'active native subagents should block fallback continue steer');
|
|
1601
|
+
const watcherState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1602
|
+
assert.equal(watcherState.ralph_continue_steer?.last_reason, 'subagents_active');
|
|
1603
|
+
assert.equal(watcherState.ralph_continue_steer?.subagent_session_id, codexSessionId);
|
|
1604
|
+
assert.deepEqual(watcherState.ralph_continue_steer?.active_subagent_thread_ids, ['sub-thread-1']);
|
|
1605
|
+
}
|
|
1606
|
+
finally {
|
|
1607
|
+
await rm(wd, { recursive: true, force: true });
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1401
1610
|
it('fails closed when Ralph hud progress is missing or invalid', async () => {
|
|
1402
1611
|
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-ralph-progress-guard-'));
|
|
1403
1612
|
const fakeBinDir = join(wd, 'fake-bin');
|
|
@@ -2263,6 +2472,85 @@ exit 0
|
|
|
2263
2472
|
await rm(tempHome, { recursive: true, force: true });
|
|
2264
2473
|
}
|
|
2265
2474
|
});
|
|
2475
|
+
it('backs off idle polling and resets to the base cadence after fresh rollout activity', async () => {
|
|
2476
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-idle-backoff-'));
|
|
2477
|
+
const tempHome = await mkdtemp(join(tmpdir(), 'omx-fallback-idle-backoff-home-'));
|
|
2478
|
+
const sid = randomUUID();
|
|
2479
|
+
const sessionDir = todaySessionDir(tempHome);
|
|
2480
|
+
const rolloutPath = join(sessionDir, `rollout-test-fallback-idle-backoff-${sid}.jsonl`);
|
|
2481
|
+
const watcherScript = new URL('../../../dist/scripts/notify-fallback-watcher.js', import.meta.url).pathname;
|
|
2482
|
+
const notifyHook = new URL('../../../dist/scripts/notify-hook.js', import.meta.url).pathname;
|
|
2483
|
+
const watcherStatePath = join(wd, '.omx', 'state', 'notify-fallback-state.json');
|
|
2484
|
+
const turnLogPath = join(wd, '.omx', 'logs', `turns-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
2485
|
+
let child;
|
|
2486
|
+
try {
|
|
2487
|
+
await mkdir(join(wd, '.omx', 'logs'), { recursive: true });
|
|
2488
|
+
await mkdir(join(wd, '.omx', 'state'), { recursive: true });
|
|
2489
|
+
await mkdir(sessionDir, { recursive: true });
|
|
2490
|
+
await writeFile(rolloutPath, `${JSON.stringify({
|
|
2491
|
+
timestamp: new Date().toISOString(),
|
|
2492
|
+
type: 'session_meta',
|
|
2493
|
+
payload: { id: `thread-${sid}`, cwd: wd },
|
|
2494
|
+
})}
|
|
2495
|
+
`);
|
|
2496
|
+
child = spawn(process.execPath, [
|
|
2497
|
+
watcherScript,
|
|
2498
|
+
'--cwd',
|
|
2499
|
+
wd,
|
|
2500
|
+
'--notify-script',
|
|
2501
|
+
notifyHook,
|
|
2502
|
+
'--poll-ms',
|
|
2503
|
+
'50',
|
|
2504
|
+
'--idle-max-poll-ms',
|
|
2505
|
+
'200',
|
|
2506
|
+
'--parent-pid',
|
|
2507
|
+
String(process.pid),
|
|
2508
|
+
'--max-lifetime-ms',
|
|
2509
|
+
'5000',
|
|
2510
|
+
], {
|
|
2511
|
+
cwd: wd,
|
|
2512
|
+
stdio: 'ignore',
|
|
2513
|
+
env: buildCleanNotifyEnv({ HOME: tempHome, OMX_NOTIFY_FALLBACK_IDLE_MAX_POLL_MS: '200' }),
|
|
2514
|
+
});
|
|
2515
|
+
await waitFor(async () => {
|
|
2516
|
+
try {
|
|
2517
|
+
const watcherState = JSON.parse(await readFile(watcherStatePath, 'utf-8'));
|
|
2518
|
+
return watcherState.adaptive_poll?.current_ms === 200 && watcherState.adaptive_poll?.idle_streak >= 2;
|
|
2519
|
+
}
|
|
2520
|
+
catch {
|
|
2521
|
+
return false;
|
|
2522
|
+
}
|
|
2523
|
+
}, 4000, 50);
|
|
2524
|
+
const freshTurnId = `turn-fresh-${sid}`;
|
|
2525
|
+
await appendLine(rolloutPath, {
|
|
2526
|
+
timestamp: new Date().toISOString(),
|
|
2527
|
+
type: 'event_msg',
|
|
2528
|
+
payload: {
|
|
2529
|
+
type: 'task_complete',
|
|
2530
|
+
turn_id: freshTurnId,
|
|
2531
|
+
last_agent_message: 'fresh message after idle backoff',
|
|
2532
|
+
},
|
|
2533
|
+
});
|
|
2534
|
+
await waitFor(async () => {
|
|
2535
|
+
const turnLines = await readLines(turnLogPath);
|
|
2536
|
+
if (!turnLines.some((line) => line.includes(freshTurnId)))
|
|
2537
|
+
return false;
|
|
2538
|
+
const watcherState = JSON.parse(await readFile(watcherStatePath, 'utf-8'));
|
|
2539
|
+
return watcherState.adaptive_poll?.current_ms === 50
|
|
2540
|
+
&& watcherState.adaptive_poll?.idle_streak === 0
|
|
2541
|
+
&& watcherState.adaptive_poll?.last_activity_reason === 'rollout_event';
|
|
2542
|
+
}, 4000, 50);
|
|
2543
|
+
}
|
|
2544
|
+
finally {
|
|
2545
|
+
if (child && isPidAlive(child.pid)) {
|
|
2546
|
+
child.kill('SIGTERM');
|
|
2547
|
+
await waitForExit(child, 4000).catch(() => { });
|
|
2548
|
+
}
|
|
2549
|
+
await rm(wd, { recursive: true, force: true });
|
|
2550
|
+
await rm(tempHome, { recursive: true, force: true });
|
|
2551
|
+
await rm(rolloutPath, { force: true });
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2266
2554
|
it('exits after the configured max lifetime', async () => {
|
|
2267
2555
|
const wd = await mkdtemp(join(tmpdir(), 'omx-fallback-max-life-'));
|
|
2268
2556
|
const tempHome = await mkdtemp(join(tmpdir(), 'omx-fallback-max-home-'));
|