"""Codex CLI: `codex exec --json ... -o last.md -` (stdin prompt), resume with `codex exec resume `. Thread id comes from the `thread.started` event in events.jsonl; the last message from last.md.""" import json from .base import ExecResult, RunnerExecutor class CodexExecutor(RunnerExecutor): stdout_name = "events.jsonl" def collect(self, handle): t, d = self.transport, handle["run_dir"] last = t.read_text(t.join(d, "last.md")) or "" thread = handle.get("thread_id") line = t.grep_first(t.join(d, "events.jsonl"), "thread.started") if line: try: thread = json.loads(line).get("thread_id") or thread except ValueError: pass tail = (self.stderr_tail(handle) + "\n" + t.tail(t.join(d, "events.jsonl"), 1)[-600:]).strip() return ExecResult(last.strip(), self.exit_code(handle), thread, self.logs(handle, "events.jsonl", "stderr.txt", "last.md"), tail)