File size: 7,280 Bytes
9b8961f
 
 
 
 
 
 
 
b89b0b0
 
9a2b78c
 
 
b89b0b0
9a2b78c
 
 
b89b0b0
9a2b78c
 
 
 
 
 
 
b89b0b0
 
 
9a2b78c
b89b0b0
 
9a2b78c
 
 
 
 
 
 
b89b0b0
9a2b78c
 
 
b89b0b0
9a2b78c
 
b89b0b0
9a2b78c
b89b0b0
9a2b78c
 
 
 
 
1d42c66
9a2b78c
 
 
 
 
b89b0b0
9a2b78c
 
 
b89b0b0
9a2b78c
 
 
 
 
b89b0b0
9a2b78c
 
 
 
 
 
b89b0b0
9a2b78c
 
 
 
 
 
 
b89b0b0
 
 
 
 
9a2b78c
 
 
 
 
 
 
b89b0b0
 
9a2b78c
 
 
 
 
1d42c66
9a2b78c
 
1d42c66
 
9a2b78c
 
 
 
1d42c66
 
 
9a2b78c
 
 
 
 
 
 
 
 
1d42c66
9a2b78c
b89b0b0
 
 
 
 
 
 
9a2b78c
 
b89b0b0
9a2b78c
 
 
 
 
 
 
b89b0b0
 
 
 
 
 
 
 
9a2b78c
b89b0b0
 
9a2b78c
b89b0b0
 
 
 
 
9a2b78c
b89b0b0
9a2b78c
b89b0b0
 
 
 
9a2b78c
b89b0b0
 
 
 
 
9a2b78c
b89b0b0
 
 
 
 
 
 
 
9a2b78c
 
b89b0b0
9a2b78c
b89b0b0
9a2b78c
b89b0b0
 
 
 
 
 
 
 
 
 
9a2b78c
 
b89b0b0
9a2b78c
 
 
 
b89b0b0
9a2b78c
b89b0b0
9a2b78c
b89b0b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a2b78c
 
 
 
 
 
 
 
 
 
 
b89b0b0
9a2b78c
b89b0b0
9a2b78c
 
 
 
 
 
 
 
 
 
20666a8
9a2b78c
 
20666a8
b89b0b0
 
9a2b78c
b89b0b0
 
 
 
 
9a2b78c
 
 
 
b89b0b0
9a2b78c
b89b0b0
9a2b78c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
---
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/<session-prefix>/
```

The approval log is:

```bash
~/.runtime/<session-prefix>/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.