"""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, parse_exit class CodexExecutor(RunnerExecutor): stdout_name = "events.jsonl" COLLECT = [("read", "exit.txt"), ("read", "last.md"), ("grep", "events.jsonl", "thread.started"), ("tail", "stderr.txt", 5), ("tail", "events.jsonl", 1)] def collect(self, handle): exit_text, last, line, err_tail, last_event = self.fetch(handle, self.COLLECT) # one remote call thread = handle.get("thread_id") if line: try: thread = json.loads(line).get("thread_id") or thread except ValueError: pass tail = (err_tail + "\n" + last_event[-600:]).strip() return ExecResult((last or "").strip(), parse_exit(exit_text), thread, self.logs(handle, "events.jsonl", "stderr.txt", "last.md"), tail)