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
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import { basename, dirname, join } from "path";
|
|
7
|
-
import { existsSync, readFileSync } from "fs";
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
8
8
|
import { constants as osConstants } from "os";
|
|
9
9
|
import { setup, SETUP_SCOPES } from "./setup.js";
|
|
10
10
|
import { uninstall } from "./uninstall.js";
|
|
@@ -30,9 +30,10 @@ import { generateOverlay, removeSessionModelInstructionsFile, resolveSessionOrch
|
|
|
30
30
|
import { readSessionState, writeSessionStart, writeSessionEnd, resetSessionMetrics, } from "../hooks/session.js";
|
|
31
31
|
import { buildClientAttachedReconcileHookName, buildReconcileHudResizeArgs, buildRegisterClientAttachedReconcileArgs, buildRegisterResizeHookArgs, buildResizeHookName, buildResizeHookTarget, buildScheduleDelayedHudResizeArgs, buildUnregisterClientAttachedReconcileArgs, buildUnregisterResizeHookArgs, enableMouseScrolling, isMsysOrGitBash, isNativeWindows, isTmuxAvailable, } from "../team/tmux-session.js";
|
|
32
32
|
import { getPackageRoot } from "../utils/package.js";
|
|
33
|
-
import { codexConfigPath } from "../utils/paths.js";
|
|
33
|
+
import { codexConfigPath, rememberOmxLaunchContext, resolveOmxEntryPath } from "../utils/paths.js";
|
|
34
34
|
import { repairConfigIfNeeded } from "../config/generator.js";
|
|
35
35
|
import { HUD_TMUX_HEIGHT_LINES } from "../hud/constants.js";
|
|
36
|
+
rememberOmxLaunchContext();
|
|
36
37
|
import { classifySpawnError, spawnPlatformCommandSync, } from "../utils/platform-command.js";
|
|
37
38
|
import { buildHookEvent } from "../hooks/extensibility/events.js";
|
|
38
39
|
import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
|
|
@@ -100,6 +101,7 @@ Options:
|
|
|
100
101
|
--madmax-spark spark model for workers + bypass approvals for leader and workers
|
|
101
102
|
(shorthand for: --spark --madmax)
|
|
102
103
|
--notify-temp Enable temporary notification routing for this run/session only
|
|
104
|
+
--tmux Launch the interactive leader session in detached tmux
|
|
103
105
|
--discord Select Discord provider for temporary notification mode
|
|
104
106
|
--slack Select Slack provider for temporary notification mode
|
|
105
107
|
--telegram Select Telegram provider for temporary notification mode
|
|
@@ -146,6 +148,11 @@ const ALLOWED_SHELLS = new Set([
|
|
|
146
148
|
]);
|
|
147
149
|
const WINDOWS_DETACHED_BOOTSTRAP_DELAY_MS = 2500;
|
|
148
150
|
const CODEX_VERSION_FLAGS = new Set(["--version", "-V"]);
|
|
151
|
+
const TMUX_EXTENDED_KEYS_MODE = "always";
|
|
152
|
+
const TMUX_EXTENDED_KEYS_FALLBACK_MODE = "off";
|
|
153
|
+
const TMUX_EXTENDED_KEYS_LEASE_DIR = "tmux-extended-keys";
|
|
154
|
+
const TMUX_EXTENDED_KEYS_LOCK_RETRY_MS = 20;
|
|
155
|
+
const TMUX_EXTENDED_KEYS_LOCK_MAX_ATTEMPTS = 100;
|
|
149
156
|
const NESTED_HELP_COMMANDS = new Set([
|
|
150
157
|
"ask",
|
|
151
158
|
"cleanup",
|
|
@@ -258,9 +265,40 @@ export function resolveNotifyTempContract(args, env = process.env) {
|
|
|
258
265
|
export function commandOwnsLocalHelp(command) {
|
|
259
266
|
return NESTED_HELP_COMMANDS.has(command);
|
|
260
267
|
}
|
|
261
|
-
|
|
268
|
+
function splitLeaderLaunchPolicyArgs(args) {
|
|
269
|
+
const remainingArgs = [];
|
|
270
|
+
let explicitPolicy;
|
|
271
|
+
let passthroughOnly = false;
|
|
272
|
+
for (const arg of args) {
|
|
273
|
+
if (passthroughOnly) {
|
|
274
|
+
remainingArgs.push(arg);
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (arg === "--") {
|
|
278
|
+
passthroughOnly = true;
|
|
279
|
+
remainingArgs.push(arg);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (arg === "--tmux") {
|
|
283
|
+
explicitPolicy = "detached-tmux";
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
remainingArgs.push(arg);
|
|
287
|
+
}
|
|
288
|
+
return { explicitPolicy, remainingArgs };
|
|
289
|
+
}
|
|
290
|
+
export function resolveLeaderLaunchPolicyOverride(args) {
|
|
291
|
+
return splitLeaderLaunchPolicyArgs(args).explicitPolicy;
|
|
292
|
+
}
|
|
293
|
+
export function resolveCodexLaunchPolicy(env = process.env, _platform = process.platform, tmuxAvailable = isTmuxAvailable(), nativeWindows = isNativeWindows(), stdinIsTTY = Boolean(process.stdin.isTTY), stdoutIsTTY = Boolean(process.stdout.isTTY), explicitPolicy) {
|
|
262
294
|
if (env.TMUX)
|
|
263
295
|
return "inside-tmux";
|
|
296
|
+
if (explicitPolicy === "detached-tmux")
|
|
297
|
+
return tmuxAvailable ? "detached-tmux" : "direct";
|
|
298
|
+
if (explicitPolicy === "direct")
|
|
299
|
+
return "direct";
|
|
300
|
+
if (_platform === "win32")
|
|
301
|
+
return "direct";
|
|
264
302
|
if (nativeWindows)
|
|
265
303
|
return "direct";
|
|
266
304
|
if (!stdinIsTTY || !stdoutIsTTY)
|
|
@@ -622,8 +660,9 @@ export async function launchWithHud(args) {
|
|
|
622
660
|
const launchCwd = process.cwd();
|
|
623
661
|
const parsedWorktree = parseWorktreeMode(args);
|
|
624
662
|
const notifyTempResult = resolveNotifyTempContract(parsedWorktree.remainingArgs, process.env);
|
|
663
|
+
const explicitLaunchPolicy = resolveLeaderLaunchPolicyOverride(notifyTempResult.passthroughArgs);
|
|
625
664
|
const codexHomeOverride = resolveCodexHomeForLaunch(launchCwd, process.env);
|
|
626
|
-
const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, isNativeWindows());
|
|
665
|
+
const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, isNativeWindows(), undefined, undefined, explicitLaunchPolicy);
|
|
627
666
|
const enableNotifyFallbackAuthority = launchPolicy === "direct";
|
|
628
667
|
const workerSparkModel = resolveWorkerSparkModel(notifyTempResult.passthroughArgs, codexHomeOverride);
|
|
629
668
|
const normalizedArgs = normalizeCodexLaunchArgs(notifyTempResult.passthroughArgs);
|
|
@@ -661,7 +700,7 @@ export async function launchWithHud(args) {
|
|
|
661
700
|
try {
|
|
662
701
|
const repaired = await repairConfigIfNeeded(codexConfigPath(), getPackageRoot());
|
|
663
702
|
if (repaired) {
|
|
664
|
-
console.log("[omx] Repaired
|
|
703
|
+
console.log("[omx] Repaired managed config.toml compatibility issue.");
|
|
665
704
|
}
|
|
666
705
|
}
|
|
667
706
|
catch {
|
|
@@ -680,7 +719,7 @@ export async function launchWithHud(args) {
|
|
|
680
719
|
const notifyTempContractRaw = notifyTempResult.contract.active
|
|
681
720
|
? serializeNotifyTempContract(notifyTempResult.contract)
|
|
682
721
|
: null;
|
|
683
|
-
runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, notifyTempContractRaw);
|
|
722
|
+
runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, notifyTempContractRaw, explicitLaunchPolicy);
|
|
684
723
|
}
|
|
685
724
|
finally {
|
|
686
725
|
// ── Phase 3: postLaunch ─────────────────────────────────────────────
|
|
@@ -721,7 +760,7 @@ export async function execWithOverlay(args) {
|
|
|
721
760
|
try {
|
|
722
761
|
const repaired = await repairConfigIfNeeded(codexConfigPath(), getPackageRoot());
|
|
723
762
|
if (repaired) {
|
|
724
|
-
console.log("[omx] Repaired
|
|
763
|
+
console.log("[omx] Repaired managed config.toml compatibility issue.");
|
|
725
764
|
}
|
|
726
765
|
}
|
|
727
766
|
catch {
|
|
@@ -755,11 +794,12 @@ export async function execWithOverlay(args) {
|
|
|
755
794
|
}
|
|
756
795
|
export function normalizeCodexLaunchArgs(args) {
|
|
757
796
|
const parsed = parseWorktreeMode(args);
|
|
797
|
+
const launchPolicyParsed = splitLeaderLaunchPolicyArgs(parsed.remainingArgs);
|
|
758
798
|
const normalized = [];
|
|
759
799
|
let wantsBypass = false;
|
|
760
800
|
let hasBypass = false;
|
|
761
801
|
let reasoningMode = null;
|
|
762
|
-
for (const arg of
|
|
802
|
+
for (const arg of launchPolicyParsed.remainingArgs) {
|
|
763
803
|
if (arg === MADMAX_FLAG) {
|
|
764
804
|
wantsBypass = true;
|
|
765
805
|
continue;
|
|
@@ -1050,20 +1090,191 @@ function detectDetachedSessionWindowIndex(sessionName) {
|
|
|
1050
1090
|
function escapeShellDoubleQuotedValue(value) {
|
|
1051
1091
|
return value.replace(/["\\$`]/g, "\\$&");
|
|
1052
1092
|
}
|
|
1053
|
-
function
|
|
1054
|
-
const
|
|
1093
|
+
function sanitizeTmuxLeaseKey(value) {
|
|
1094
|
+
const cleaned = value
|
|
1095
|
+
.toLowerCase()
|
|
1096
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
1097
|
+
.replace(/^-+|-+$/g, "");
|
|
1098
|
+
return cleaned || "default";
|
|
1099
|
+
}
|
|
1100
|
+
function blockMs(ms) {
|
|
1101
|
+
const delay = Math.max(1, Math.floor(ms));
|
|
1102
|
+
const shared = new SharedArrayBuffer(4);
|
|
1103
|
+
const view = new Int32Array(shared);
|
|
1104
|
+
Atomics.wait(view, 0, 0, delay);
|
|
1105
|
+
}
|
|
1106
|
+
function tmuxExtendedKeysLeaseRoot(cwd) {
|
|
1107
|
+
return join(cwd, ".omx", "state", TMUX_EXTENDED_KEYS_LEASE_DIR);
|
|
1108
|
+
}
|
|
1109
|
+
function resolveTmuxSocketPath(execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
|
|
1110
|
+
encoding: "utf-8",
|
|
1111
|
+
})) {
|
|
1112
|
+
return (execTmuxSync(["display-message", "-p", "#{socket_path}"], execFileSyncImpl) ||
|
|
1113
|
+
"default");
|
|
1114
|
+
}
|
|
1115
|
+
function tmuxExtendedKeysLeasePath(cwd, socketPath) {
|
|
1116
|
+
return join(tmuxExtendedKeysLeaseRoot(cwd), `${sanitizeTmuxLeaseKey(socketPath)}.json`);
|
|
1117
|
+
}
|
|
1118
|
+
function readTmuxExtendedKeysLeaseState(leasePath) {
|
|
1119
|
+
if (!existsSync(leasePath))
|
|
1120
|
+
return null;
|
|
1121
|
+
try {
|
|
1122
|
+
const parsed = JSON.parse(readFileSync(leasePath, "utf-8"));
|
|
1123
|
+
if (typeof parsed.originalMode !== "string" ||
|
|
1124
|
+
!Array.isArray(parsed.holders) ||
|
|
1125
|
+
!parsed.holders.every((holder) => typeof holder === "string")) {
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
return {
|
|
1129
|
+
originalMode: parsed.originalMode,
|
|
1130
|
+
holders: [...parsed.holders],
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
catch {
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function writeTmuxExtendedKeysLeaseState(leasePath, state) {
|
|
1138
|
+
mkdirSync(dirname(leasePath), { recursive: true });
|
|
1139
|
+
writeFileSync(leasePath, JSON.stringify(state, null, 2));
|
|
1140
|
+
}
|
|
1141
|
+
function withTmuxExtendedKeysLeaseLock(cwd, socketPath, run) {
|
|
1142
|
+
const leaseRoot = tmuxExtendedKeysLeaseRoot(cwd);
|
|
1143
|
+
mkdirSync(leaseRoot, { recursive: true });
|
|
1144
|
+
const lockPath = join(leaseRoot, `${sanitizeTmuxLeaseKey(socketPath)}.lock`);
|
|
1145
|
+
for (let attempt = 0; attempt < TMUX_EXTENDED_KEYS_LOCK_MAX_ATTEMPTS; attempt++) {
|
|
1146
|
+
try {
|
|
1147
|
+
mkdirSync(lockPath);
|
|
1148
|
+
try {
|
|
1149
|
+
return run();
|
|
1150
|
+
}
|
|
1151
|
+
finally {
|
|
1152
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
catch (err) {
|
|
1156
|
+
const code = err && typeof err === "object" && "code" in err
|
|
1157
|
+
? String(err.code)
|
|
1158
|
+
: "";
|
|
1159
|
+
if (code !== "EEXIST")
|
|
1160
|
+
throw err;
|
|
1161
|
+
blockMs(TMUX_EXTENDED_KEYS_LOCK_RETRY_MS);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
throw new Error(`timed out waiting for tmux extended-keys lease lock: ${lockPath}`);
|
|
1165
|
+
}
|
|
1166
|
+
function buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd) {
|
|
1167
|
+
const wrapped = [
|
|
1168
|
+
buildTmuxExtendedKeysAcquireShellSnippet(cwd),
|
|
1169
|
+
"omx_detached_session_cleanup() {",
|
|
1055
1170
|
"status=$?;",
|
|
1056
1171
|
"trap - 0 INT TERM HUP;",
|
|
1172
|
+
buildTmuxExtendedKeysReleaseShellSnippet(cwd),
|
|
1057
1173
|
`tmux kill-session -t "${escapeShellDoubleQuotedValue(sessionName)}" >/dev/null 2>&1 || true;`,
|
|
1058
1174
|
"exit $status;",
|
|
1175
|
+
"};",
|
|
1176
|
+
"trap omx_detached_session_cleanup 0 INT TERM HUP;",
|
|
1177
|
+
codexCmd,
|
|
1059
1178
|
].join(" ");
|
|
1060
|
-
const wrapped = [`trap '${cleanupTrap}' 0 INT TERM HUP;`, codexCmd].join(" ");
|
|
1061
1179
|
return `/bin/sh -lc ${quoteShellArg(wrapped)}`;
|
|
1062
1180
|
}
|
|
1181
|
+
function execTmuxSync(args, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
|
|
1182
|
+
encoding: "utf-8",
|
|
1183
|
+
})) {
|
|
1184
|
+
return execFileSyncImpl("tmux", [...args]).trim();
|
|
1185
|
+
}
|
|
1186
|
+
export function acquireTmuxExtendedKeysLease(cwd, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
|
|
1187
|
+
encoding: "utf-8",
|
|
1188
|
+
})) {
|
|
1189
|
+
try {
|
|
1190
|
+
const socketPath = resolveTmuxSocketPath(execFileSyncImpl);
|
|
1191
|
+
const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
|
|
1192
|
+
const leaseId = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
1193
|
+
withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
|
|
1194
|
+
const state = readTmuxExtendedKeysLeaseState(leasePath);
|
|
1195
|
+
if (!state || state.holders.length === 0) {
|
|
1196
|
+
const previousMode = execTmuxSync(["show-options", "-sv", "extended-keys"], execFileSyncImpl) ||
|
|
1197
|
+
TMUX_EXTENDED_KEYS_FALLBACK_MODE;
|
|
1198
|
+
execTmuxSync(["set-option", "-sq", "extended-keys", TMUX_EXTENDED_KEYS_MODE], execFileSyncImpl);
|
|
1199
|
+
writeTmuxExtendedKeysLeaseState(leasePath, {
|
|
1200
|
+
originalMode: previousMode,
|
|
1201
|
+
holders: [leaseId],
|
|
1202
|
+
});
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
state.holders.push(leaseId);
|
|
1206
|
+
writeTmuxExtendedKeysLeaseState(leasePath, state);
|
|
1207
|
+
});
|
|
1208
|
+
return `${socketPath}\t${leaseId}`;
|
|
1209
|
+
}
|
|
1210
|
+
catch (err) {
|
|
1211
|
+
process.stderr.write(`[cli/index] operation failed: ${err}\n`);
|
|
1212
|
+
return null;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
export function releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
|
|
1216
|
+
encoding: "utf-8",
|
|
1217
|
+
})) {
|
|
1218
|
+
if (!leaseHandle.trim())
|
|
1219
|
+
return;
|
|
1220
|
+
const [socketPathRaw = "", leaseId = ""] = leaseHandle.split("\t");
|
|
1221
|
+
const socketPath = socketPathRaw.trim() || "default";
|
|
1222
|
+
if (!leaseId)
|
|
1223
|
+
return;
|
|
1224
|
+
try {
|
|
1225
|
+
const leasePath = tmuxExtendedKeysLeasePath(cwd, socketPath);
|
|
1226
|
+
withTmuxExtendedKeysLeaseLock(cwd, socketPath, () => {
|
|
1227
|
+
const state = readTmuxExtendedKeysLeaseState(leasePath);
|
|
1228
|
+
if (!state || state.holders.length === 0) {
|
|
1229
|
+
rmSync(leasePath, { force: true });
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
const holders = state.holders.filter((holder) => holder !== leaseId);
|
|
1233
|
+
if (holders.length > 0) {
|
|
1234
|
+
writeTmuxExtendedKeysLeaseState(leasePath, {
|
|
1235
|
+
originalMode: state.originalMode,
|
|
1236
|
+
holders,
|
|
1237
|
+
});
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
execTmuxSync(["set-option", "-sq", "extended-keys", state.originalMode], execFileSyncImpl);
|
|
1241
|
+
rmSync(leasePath, { force: true });
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
catch (err) {
|
|
1245
|
+
process.stderr.write(`[cli/index] operation failed: ${err}\n`);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
function buildTmuxExtendedKeysHelperCommand(cwd, operation) {
|
|
1249
|
+
const cwdLiteral = JSON.stringify(cwd);
|
|
1250
|
+
const moduleUrlLiteral = JSON.stringify(import.meta.url);
|
|
1251
|
+
const script = operation === "acquire"
|
|
1252
|
+
? `const mod = await import(${moduleUrlLiteral}); const lease = mod.acquireTmuxExtendedKeysLease(${cwdLiteral}); if (lease) process.stdout.write(lease);`
|
|
1253
|
+
: `const mod = await import(${moduleUrlLiteral}); mod.releaseTmuxExtendedKeysLease(${cwdLiteral}, process.argv[1] ?? "");`;
|
|
1254
|
+
return `${quoteShellArg(process.execPath)} --input-type=module -e ${quoteShellArg(script)}`;
|
|
1255
|
+
}
|
|
1256
|
+
function buildTmuxExtendedKeysAcquireShellSnippet(cwd) {
|
|
1257
|
+
return `OMX_TMUX_EXTENDED_KEYS_LEASE=$(${buildTmuxExtendedKeysHelperCommand(cwd, "acquire")} 2>/dev/null || true);`;
|
|
1258
|
+
}
|
|
1259
|
+
function buildTmuxExtendedKeysReleaseShellSnippet(cwd) {
|
|
1260
|
+
return `if [ -n "\${OMX_TMUX_EXTENDED_KEYS_LEASE:-}" ]; then ${buildTmuxExtendedKeysHelperCommand(cwd, "release")} "\${OMX_TMUX_EXTENDED_KEYS_LEASE}" >/dev/null 2>&1 || true; fi;`;
|
|
1261
|
+
}
|
|
1262
|
+
export function withTmuxExtendedKeys(cwd, run, execFileSyncImpl = (file, tmuxArgs) => execFileSync(file, tmuxArgs, {
|
|
1263
|
+
encoding: "utf-8",
|
|
1264
|
+
})) {
|
|
1265
|
+
const leaseHandle = acquireTmuxExtendedKeysLease(cwd, execFileSyncImpl);
|
|
1266
|
+
try {
|
|
1267
|
+
return run();
|
|
1268
|
+
}
|
|
1269
|
+
finally {
|
|
1270
|
+
if (leaseHandle)
|
|
1271
|
+
releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1063
1274
|
export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId) {
|
|
1064
1275
|
const detachedLeaderCmd = nativeWindows
|
|
1065
1276
|
? "powershell.exe"
|
|
1066
|
-
: buildDetachedSessionLeaderCommand(sessionName, codexCmd);
|
|
1277
|
+
: buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd);
|
|
1067
1278
|
const newSessionArgs = [
|
|
1068
1279
|
"new-session",
|
|
1069
1280
|
"-d",
|
|
@@ -1197,6 +1408,13 @@ export function buildNotifyFallbackWatcherEnv(env = process.env, options = {}) {
|
|
|
1197
1408
|
OMX_HUD_AUTHORITY: options.enableAuthority ? "1" : "0",
|
|
1198
1409
|
};
|
|
1199
1410
|
}
|
|
1411
|
+
export function shouldEnableNotifyFallbackWatcher(env = process.env, platform = process.platform) {
|
|
1412
|
+
const toggle = String(env.OMX_NOTIFY_FALLBACK ?? "").trim();
|
|
1413
|
+
if (platform === "win32") {
|
|
1414
|
+
return toggle === "1";
|
|
1415
|
+
}
|
|
1416
|
+
return toggle !== "0";
|
|
1417
|
+
}
|
|
1200
1418
|
export async function cleanupLaunchOrphanedMcpProcesses(dependencies = {}) {
|
|
1201
1419
|
return cleanupOmxMcpProcesses([], {
|
|
1202
1420
|
...dependencies,
|
|
@@ -1204,6 +1422,24 @@ export async function cleanupLaunchOrphanedMcpProcesses(dependencies = {}) {
|
|
|
1204
1422
|
writeLine: dependencies.writeLine ?? (() => { }),
|
|
1205
1423
|
});
|
|
1206
1424
|
}
|
|
1425
|
+
export async function reapPostLaunchOrphanedMcpProcesses(dependencies = {}) {
|
|
1426
|
+
const cleanup = dependencies.cleanup ?? cleanupLaunchOrphanedMcpProcesses;
|
|
1427
|
+
const writeInfo = dependencies.writeInfo ?? console.log;
|
|
1428
|
+
const writeWarn = dependencies.writeWarn ?? console.warn;
|
|
1429
|
+
const writeError = dependencies.writeError ?? ((line) => process.stderr.write(line));
|
|
1430
|
+
try {
|
|
1431
|
+
const result = await cleanup();
|
|
1432
|
+
if (result.terminatedCount > 0) {
|
|
1433
|
+
writeInfo(`[omx] postLaunch: reaped ${result.terminatedCount} orphaned OMX MCP process(es).`);
|
|
1434
|
+
}
|
|
1435
|
+
if (result.failedPids.length > 0) {
|
|
1436
|
+
writeWarn(`[omx] postLaunch: failed to reap ${result.failedPids.length} orphaned OMX MCP process(es); continuing cleanup.`);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
catch (err) {
|
|
1440
|
+
writeError(`[cli/index] postLaunch MCP cleanup failed: ${err}\n`);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1207
1443
|
/**
|
|
1208
1444
|
* preLaunch: Prepare environment before Codex starts.
|
|
1209
1445
|
* 1. Best-effort launch-safe orphan cleanup for detached OMX MCP processes
|
|
@@ -1307,10 +1543,13 @@ ${launchAppendix}`
|
|
|
1307
1543
|
* runCodex: Launch Codex CLI (blocks until exit).
|
|
1308
1544
|
* All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
|
|
1309
1545
|
*/
|
|
1310
|
-
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, notifyTempContractRaw) {
|
|
1546
|
+
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, notifyTempContractRaw, explicitLaunchPolicy) {
|
|
1311
1547
|
const launchArgs = injectModelInstructionsBypassArgs(cwd, args, process.env, sessionModelInstructionsPath(cwd, sessionId));
|
|
1312
1548
|
const nativeWindows = isNativeWindows();
|
|
1313
|
-
const omxBin =
|
|
1549
|
+
const omxBin = resolveOmxEntryPath();
|
|
1550
|
+
if (!omxBin) {
|
|
1551
|
+
throw new Error("Unable to resolve OMX launcher path for tmux HUD bootstrap");
|
|
1552
|
+
}
|
|
1314
1553
|
const hudCmd = nativeWindows
|
|
1315
1554
|
? buildWindowsPromptCommand("node", [omxBin, "hud", "--watch"])
|
|
1316
1555
|
: buildTmuxPaneCommand("node", [omxBin, "hud", "--watch"]);
|
|
@@ -1326,7 +1565,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, n
|
|
|
1326
1565
|
const codexEnvWithNotify = notifyTempContractRaw
|
|
1327
1566
|
? { ...codexEnv, [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw }
|
|
1328
1567
|
: codexEnv;
|
|
1329
|
-
const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, nativeWindows);
|
|
1568
|
+
const launchPolicy = resolveCodexLaunchPolicy(process.env, process.platform, undefined, nativeWindows, undefined, undefined, explicitLaunchPolicy);
|
|
1330
1569
|
if (isCodexVersionRequest(launchArgs)) {
|
|
1331
1570
|
runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
|
|
1332
1571
|
return;
|
|
@@ -1376,7 +1615,9 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, n
|
|
|
1376
1615
|
catch { }
|
|
1377
1616
|
}
|
|
1378
1617
|
try {
|
|
1379
|
-
|
|
1618
|
+
withTmuxExtendedKeys(cwd, () => {
|
|
1619
|
+
runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
|
|
1620
|
+
});
|
|
1380
1621
|
}
|
|
1381
1622
|
finally {
|
|
1382
1623
|
const cleanupPaneIds = buildHudPaneCleanupTargets(listHudWatchPaneIdsInCurrentWindow(currentPaneId), hudPaneId, currentPaneId);
|
|
@@ -1598,6 +1839,8 @@ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbac
|
|
|
1598
1839
|
process.stderr.write(`[cli/index] operation failed: ${err}\n`);
|
|
1599
1840
|
// Non-fatal
|
|
1600
1841
|
}
|
|
1842
|
+
// 0. Reap MCP orphans left behind by the session that just exited.
|
|
1843
|
+
await reapPostLaunchOrphanedMcpProcesses();
|
|
1601
1844
|
// 0. Flush fallback watcher once to reduce race with fast codex exit.
|
|
1602
1845
|
try {
|
|
1603
1846
|
await flushNotifyFallbackOnce(cwd, { codexHomeOverride, enableAuthority: enableNotifyFallbackAuthority, sessionId });
|
|
@@ -1685,6 +1928,15 @@ async function postLaunch(cwd, sessionId, codexHomeOverride, enableNotifyFallbac
|
|
|
1685
1928
|
process.stderr.write(`[cli/index] operation failed: ${err}\n`);
|
|
1686
1929
|
// Non-fatal: notification failures must never block session cleanup
|
|
1687
1930
|
}
|
|
1931
|
+
// 4.5. Persist team leader attention when an active leader session exits.
|
|
1932
|
+
try {
|
|
1933
|
+
const { markOwnedTeamsLeaderSessionStopped } = await import("../team/state.js");
|
|
1934
|
+
await markOwnedTeamsLeaderSessionStopped(cwd, sessionId);
|
|
1935
|
+
}
|
|
1936
|
+
catch (err) {
|
|
1937
|
+
process.stderr.write(`[cli/index] operation failed: ${err}\n`);
|
|
1938
|
+
// Non-fatal
|
|
1939
|
+
}
|
|
1688
1940
|
// 5. Dispatch native hook event (best effort)
|
|
1689
1941
|
try {
|
|
1690
1942
|
const durationMs = sessionStartedAt
|
|
@@ -1811,6 +2063,30 @@ function parseWatcherPidFile(content) {
|
|
|
1811
2063
|
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
1812
2064
|
}
|
|
1813
2065
|
}
|
|
2066
|
+
export async function reapStaleNotifyFallbackWatcher(pidPath, deps = {}) {
|
|
2067
|
+
const exists = deps.exists ?? existsSync;
|
|
2068
|
+
if (!exists(pidPath))
|
|
2069
|
+
return;
|
|
2070
|
+
const { readFile } = await import("fs/promises");
|
|
2071
|
+
const readFileImpl = deps.readFile ?? readFile;
|
|
2072
|
+
const tryKillPidImpl = deps.tryKillPid ?? tryKillPid;
|
|
2073
|
+
const hasErrnoCodeImpl = deps.hasErrnoCode ?? hasErrnoCode;
|
|
2074
|
+
const warn = deps.warn ?? console.warn;
|
|
2075
|
+
try {
|
|
2076
|
+
const prevPid = parseWatcherPidFile(await readFileImpl(pidPath, "utf-8"));
|
|
2077
|
+
if (prevPid) {
|
|
2078
|
+
tryKillPidImpl(prevPid, "SIGTERM");
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
catch (error) {
|
|
2082
|
+
if (!hasErrnoCodeImpl(error, "ESRCH")) {
|
|
2083
|
+
warn("[omx] warning: failed to stop stale notify fallback watcher", {
|
|
2084
|
+
path: pidPath,
|
|
2085
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
1814
2090
|
function tryKillPid(pid, signal = "SIGTERM") {
|
|
1815
2091
|
try {
|
|
1816
2092
|
process.kill(pid, signal);
|
|
@@ -1824,32 +2100,16 @@ function tryKillPid(pid, signal = "SIGTERM") {
|
|
|
1824
2100
|
}
|
|
1825
2101
|
}
|
|
1826
2102
|
async function startNotifyFallbackWatcher(cwd, options = {}) {
|
|
1827
|
-
|
|
1828
|
-
return;
|
|
1829
|
-
const { mkdir, writeFile, readFile } = await import("fs/promises");
|
|
2103
|
+
const { mkdir, writeFile } = await import("fs/promises");
|
|
1830
2104
|
const pidPath = notifyFallbackPidPath(cwd);
|
|
2105
|
+
await reapStaleNotifyFallbackWatcher(pidPath);
|
|
2106
|
+
if (!shouldEnableNotifyFallbackWatcher(process.env, process.platform))
|
|
2107
|
+
return;
|
|
1831
2108
|
const pkgRoot = getPackageRoot();
|
|
1832
2109
|
const watcherScript = resolveNotifyFallbackWatcherScript(pkgRoot);
|
|
1833
2110
|
const notifyScript = resolveNotifyHookScript(pkgRoot);
|
|
1834
2111
|
if (!existsSync(watcherScript) || !existsSync(notifyScript))
|
|
1835
2112
|
return;
|
|
1836
|
-
// Stop stale watcher from a previous run.
|
|
1837
|
-
if (existsSync(pidPath)) {
|
|
1838
|
-
try {
|
|
1839
|
-
const prevPid = parseWatcherPidFile(await readFile(pidPath, "utf-8"));
|
|
1840
|
-
if (prevPid) {
|
|
1841
|
-
tryKillPid(prevPid, "SIGTERM");
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
catch (error) {
|
|
1845
|
-
if (!hasErrnoCode(error, "ESRCH")) {
|
|
1846
|
-
console.warn("[omx] warning: failed to stop stale notify fallback watcher", {
|
|
1847
|
-
path: pidPath,
|
|
1848
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1849
|
-
});
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
2113
|
await mkdir(join(cwd, ".omx", "state"), { recursive: true }).catch((error) => {
|
|
1854
2114
|
console.warn("[omx] warning: failed to create notify fallback watcher state directory", {
|
|
1855
2115
|
cwd,
|
|
@@ -2003,6 +2263,8 @@ async function stopHookDerivedWatcher(cwd) {
|
|
|
2003
2263
|
});
|
|
2004
2264
|
}
|
|
2005
2265
|
async function flushNotifyFallbackOnce(cwd, options = {}) {
|
|
2266
|
+
if (!shouldEnableNotifyFallbackWatcher(process.env, process.platform))
|
|
2267
|
+
return;
|
|
2006
2268
|
const { spawnSync } = await import("child_process");
|
|
2007
2269
|
const pkgRoot = getPackageRoot();
|
|
2008
2270
|
const watcherScript = resolveNotifyFallbackWatcherScript(pkgRoot);
|