A Better Codex CLI Wrapper (with Logs + Defaults)

Why use Codex CLI?

Most people stick to the ChatGPT app or web UI. But the Codex CLI has its own strengths:

Faster iteration — run prompts right in your terminal, no context switching.
Scriptable — pipe inputs/outputs into files, logs, or other tools.
Versionable — treat your prompts like code, commit them alongside your project.
Precise control — pass flags for models, reasoning effort, or exports without hunting through menus.
Headless workflows — perfect for servers, automation, or integrating into dev environments.

If you’re working on AI-powered projects daily, Codex CLI1 feels less like “chatting with a bot” and more like adding a reliable command-line tool to your stack.

The Problem

That said, I kept running into little annoyances:

“cursor position” errors when the TTY wasn’t happy
forgetting the same flags over and over
(-m gpt-5 -c model_reasoning_effort=”high”)
no simple log trail of my runs

So here’s a small Zsh wrapper that fixes all three.

Codex CLI Wrapper Features

Sane defaults → –full-auto -m gpt-5 -c ‘model_reasoning_effort=”high”‘
Logging → raw + cleaned output saved per run, plus a rolling session-YYYY-MM-DD.log
Exports → optional –export-ndjson and –export-md for structured or pretty summaries
Bypassable → run command codex … to call the real binary, ignoring the wrapper


The Wrapper

unalias codex 2>/dev/null
codex() {
  local logdate nodefaults
  if [[ "$1" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
    logdate="$1"; shift
  else
    logdate="$(date +%F)"
  fi

  local export_md="" export_json="" args=()
  while (( $# )); do
    case "$1" in
      --export-md)     export_md=1; shift ;;
      --export-ndjson) export_json=1; shift ;;
      --no-defaults)   nodefaults=1; shift ;;
      *)               args+=("$1"); shift ;;
    esac
  done

  mkdir -p .agent-codex 2>/dev/null
  local model_default="${CODEX_MODEL:-gpt-5}"
  local config_default='model_reasoning_effort="high"'

  local have_model=0 have_fullauto=0 have_config=0 cleaned_args=()
  for a in "${args[@]}"; do
    [[ "$a" == "-m" || "$a" == "--model" ]] && have_model=1
    [[ "$a" == "--full-auto" ]] && have_fullauto=1
    [[ "$a" == "-c" ]] && have_config=1
    cleaned_args+=("$a")
  done

  local final_args=()
  if [[ -z "$nodefaults" ]]; then
    [[ $have_fullauto -eq 0 ]] && final_args+=( --full-auto )
    [[ $have_model -eq 0 ]] && final_args+=( -m "$model_default" )
    [[ $have_config -eq 0 ]] && final_args+=( -c "$config_default" )
  fi
  final_args+=( "${cleaned_args[@]}" )

  local run_id="$(date +%Y-%m-%d_%H-%M-%S)"
  local roll_log=".agent-codex/session-${logdate}.log"
  local tmp_out=".agent-codex/.tmp.${run_id}.out"

  if command -v script >/dev/null 2>&1; then
    script -q /dev/null codex "${final_args[@]}" \
      | tee "$tmp_out" \
      | perl -pe 's/\e\[[0-9;]*[A-Za-z]//g' >> "$roll_log"
  else
    command codex "${final_args[@]}" \
      | tee "$tmp_out" \
      | perl -pe 's/\e\[[0-9;]*[A-Za-z]//g' >> "$roll_log"
  fi

  rm -f "$tmp_out"
}

Usage:

codex "Explain this codebase"   # runs with defaults
codex --no-defaults -m gpt-4.1  # bypass defaults
codex --export-md "Summarize…"  # also saves a Markdown session file

Logs land in .agent-codex/ automatically.

Why This Helps

It’s a tiny change, but it makes Codex feel smoother:

No more broken pipe errors
Consistent run history for review
One less mental burden remembering flags

✅ Copy this into your ~/.zshrc, source ~/.zshrc, and you’re good.

  1. Codex CLI
    https://github.com/openai/codex ↩︎

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top