--- tags: - codex - tmux - automation - developer-tools --- # codex_exec `codex_exec` is an unofficial launcher for the interactive OpenAI Codex TUI. It starts a real interactive `codex` session inside `tmux` and runs a watcher that automatically confirms recognized Codex approval and selection overlays. Despite the repository name, this is not `codex exec` and it does not turn Codex into a non-interactive subprocess. You can attach to the TUI, type follow-up messages, detach, reattach, and resume persisted Codex conversations. The project is intentionally small and self-contained: - `codex_auto_run.py`: the launcher and approval watcher. - `test_codex_auto_run.py`: unit tests for detection, argument handling, and daemon lifecycle behavior. - `LOCAL_SETUP.txt`: optional `runx` Bash setup. - `README.md`: this document. ## Requirements - Linux. The watcher uses `fcntl`, `/proc`, and `tmux`. - Python 3.10 or newer. - `tmux` available on `PATH`. - Codex CLI installed, authenticated, and available as `codex` on `PATH`, or supplied with `--codex-binary`. The watcher recognizes text rendered by the Codex TUI. If a future Codex release changes approval wording or layout, detector updates may be required. ## Current Approval Policy By default, Codex still starts with `on-request` approvals and the `workspace-write` sandbox. The watcher then confirms recognized overlays after the screen is stable for multiple polls. The current default is broad auto-approval. It confirms the currently selected option when that option is not an obvious negative or cancel choice. Automatically confirmed by default: - shell command approvals; - file edit approvals; - permission approvals; - network access approvals; - MCP/app/tool approvals; - directory trust prompts; - full-access prompts; - hook/plugin prompts; - ordinary multi-choice prompts such as `Questions 1/1`; - persistent approval rows such as "don't ask again", session-wide approvals, or future host approvals, if that row is currently selected. The watcher will not confirm an option whose label starts with an obvious negative/cancel prefix such as `No`, `Cancel`, `Deny`, `Reject`, `Quit`, `Do not`, or `Don't`. This removes the human review normally provided by an approval prompt. A mistaken or prompt-injected Codex action may delete files, run untrusted commands, disclose accessible data over the network, request broader permissions, choose an unintended default answer, or act through connected apps. Use this only in an environment where those side effects are acceptable. Useful opt-out switches: ```bash ./codex_auto_run.py --no-approve-mcp ... ./codex_auto_run.py --no-auto-trust-directory ... ``` `--bypass` is more dangerous: it passes Codex's `--dangerously-bypass-approvals-and-sandbox` option and should only be used inside an externally isolated container or VM. ## Install Or Migrate Clone the repository on the target machine: ```bash git clone https://huggingface.co/yitongl/codex_exec cd codex_exec chmod +x codex_auto_run.py PYTHONDONTWRITEBYTECODE=1 python3 -m unittest -v test_codex_auto_run.py ``` Run directly from the clone: ```bash ./codex_auto_run.py -C ~/code/my_project -p "Inspect the project and run tests." ``` ## Optional `runx` Command `LOCAL_SETUP.txt` provides a Bash function named `runx`. It derives a tmux session prefix from the current directory, so different projects get separate watcher state and logs. The default `runx` setup expects the launcher at `$HOME/codex_auto_run.py`. Install it like this: ```bash git clone https://huggingface.co/yitongl/codex_exec ~/codex_exec cp ~/codex_exec/codex_auto_run.py ~/codex_auto_run.py chmod +x ~/codex_auto_run.py cp ~/codex_exec/LOCAL_SETUP.txt ~/.bash_aliases source ~/.bashrc ``` Then use it from any project directory: ```bash cd ~/code/my_project runx -p "Implement the requested change and verify it." ``` If you want to keep the script somewhere else, edit the path in `LOCAL_SETUP.txt` before copying it to `~/.bash_aliases`. ## Start A Session ```bash ./codex_auto_run.py \ -C ~/code/my_project \ -p "Implement the requested change, run the tests, and summarize the result." ``` The launcher creates a uniquely named `tmux` session and normally attaches to it immediately. Startup output includes: - the tmux session name; - the Codex binary path; - the working directory; - the approval log path; - the reattach command. Use a UTF-8 prompt file for long tasks: ```bash ./codex_auto_run.py -C ~/code/my_project --prompt-file task.md ``` Start without attaching: ```bash ./codex_auto_run.py --detach -C ~/code/my_project -p "Run the full task." ``` Reattach later: ```bash tmux attach -t codex-auto-YYYYMMDD-HHMMSS-PID-RANDOM ``` Inside `tmux`, press `Ctrl-b d` to detach without stopping Codex. ## Resume Resume the most recent interactive conversation for a working directory: ```bash ./codex_auto_run.py --resume-last -C ~/code/my_project -p "Continue and verify." ``` Resume a specific Codex session ID or name: ```bash ./codex_auto_run.py --resume SESSION_ID -C ~/code/my_project -p "Continue." ``` Open Codex's interactive session picker: ```bash ./codex_auto_run.py --resume -C ~/code/my_project ``` The picker form cannot be combined with `-p` or `--prompt-file`; select the conversation first, then type in Codex. ## Pass Codex Options Put Codex-specific global options after `--`: ```bash ./codex_auto_run.py \ -C ~/code/my_project \ -p "Research and implement the task." \ -- \ --search \ --model MODEL_NAME ``` The wrapper reserves `-p` for the initial or resumed-session follow-up prompt. Use `--codex-profile PROFILE_NAME` for Codex's own profile option. Some Codex options conflict with wrapper-managed behavior and are rejected, including Codex's own approval, sandbox, working-directory, full-auto, and bypass flags. Use the wrapper's `--sandbox`, `-C`, and `--bypass` options instead. ## Watcher Status, Logs, And Control Show status: ```bash ./codex_auto_run.py --status ``` Stop the watcher: ```bash ./codex_auto_run.py --stop-daemon ``` Start only the watcher: ```bash ./codex_auto_run.py --start-daemon ``` Default runtime state and logs are stored under: ```bash ~/.runtime// ``` The approval log is: ```bash ~/.runtime//approve-debug.log ``` For the default direct launcher prefix this is: ```bash ~/.runtime/codex-auto/approve-debug.log ``` For `runx`, the prefix is based on the current directory and ends in `-x`. For example, running from `$HOME` uses: ```bash ~/.runtime/home-x/approve-debug.log ``` Log events include `daemon_start`, `launcher_ready`, `pending`, `approve`, `approve_failed`, `clear_active`, `daemon_exit`, and `daemon_stop`. ## Tests Run the unit tests: ```bash PYTHONDONTWRITEBYTECODE=1 python3 -m unittest -v test_codex_auto_run.py ``` The tests do not start a real Codex session. They cover approval-screen detection, broad default approval behavior, opt-out switches, argument validation, resume command construction, binary probing, tmux command construction, and daemon lifecycle safeguards. ## Project Status This project is independent and unofficial. It is not an OpenAI product and is not endorsed or supported by OpenAI.