Loading

    Optimize Codex Configuration for Blazing-Fast CLI Automation

    John Lindquist
    John Lindquist

    By default, OpenAI Codex loads an enormous amount of context for every interaction—including all your skills, plugins, and project files. This can result in prompts exceeding 14,000 tokens, making it slow and costly, especially for simple, single-purpose tasks like controlling a complex CLI.

    This lesson demonstrates how to bypass this default behavior to create hyper-focused, low-token AI agents for any command-line tool. By using specific Codex flags and a custom ZSH alias, you can strip away all unnecessary context and inject a targeted system prompt (such as a CLI's help documentation).

    The result is a specialized AI wrapper with a drastically reduced token count (from 14k+ down to ~4k), enabling the use of faster, cheaper models like gpt-5.3-codex-spark. This makes it practical to build natural language interfaces for tools like cmux, git, or ffmpeg, transforming how you interact with your terminal.

    The Problem

    • The default Codex setup loads excessive context, leading to slow responses and high token usage.
    • This makes it impractical to use for quick, single-purpose CLI interactions.
    • Large context requirements limit the use of faster, more cost-effective AI models.

    The Solution: A Focused AI Wrapper

    This lesson teaches you to create a custom ZSH function that invokes Codex with a minimal, highly-relevant context.

    How it Works:

    1. Disable Defaults: Use flags to turn off plugins, skills instructions, app instructions, and memories.
    2. Inject CLI Context: Pass the CLI's help text or usage documentation as the developer_instructions.
    3. Target a Fast Model: Specify a lightweight model like gpt-5.3-codex-spark with low reasoning effort.
    4. Create Aliases: Set up short aliases (cxi for interactive, cx for one-shot commands) for quick access.

    Benefits:

    • Massive Token Reduction: Lower API costs by reducing the prompt size by over 70%.
    • Blazing-Fast Responses: Get near-instantaneous command generation from the AI.
    • Natural Language Control: Interact with complex CLIs using simple English commands without memorizing flags.
    • Reusable and Extensible: Apply this pattern to create specialized AI helpers for any CLI tool in your workflow.

    By the end of this lesson, you'll have a powerful technique for building efficient, custom AI tools that streamline your command-line experience.

    Prompts

    Create three new panes.
    Please close those three panes.
    Rename this tab to Strawberry.

    Terminal Commands

    # Check the default prompt input and its large context
    codex debug prompt-input
    # Pipe the default prompt to a token counter to see the high token count
    codex debug prompt-input | count-tokens
    # The custom alias for an interactive, focused cmux session
    cxi
    # View the source of the custom ZSH function
    which cxi
    # Check the prompt input for the custom, focused wrapper
    cxi debug prompt-input
    # Count the tokens for the focused wrapper, showing a massive reduction
    cxi debug prompt-input | count-tokens
    # Use the one-shot alias to execute a command directly
    cx "Rename this tab to Strawberry."

    Full Gist

    Source: https://gist.github.com/johnlindquist/37f8ecb48e9553577eb8365c9a246310

    49-codex-bare-dsl.zsh

    # =========================
    # codex bare (care)
    # =========================
    # "care" = "codex bare" — runs `codex debug prompt-input` with all
    # context-bloating sources suppressed:
    # - plugins disabled (--disable plugins)
    # - AGENTS.md suppressed (-c project_doc_max_bytes=0)
    # - skills block suppressed (-c skills.include_instructions=false)
    # - clean HOME (HOME=/tmp/empty-home, no ~/.agents skills)
    # - clean CODEX_HOME (CODEX_HOME=/tmp/empty-codex-home)
    #
    # Usage:
    # care [prompt]
    # care -s "system prompt" [prompt]
    # care --help
    #
    # spark — alias for care with model forced to gpt-5.3-codex-spark
    care() {
    local system_prompt=""
    local model=""
    local -a extra_args=()
    while [[ $# -gt 0 ]]; do
    case "$1" in
    -s|--system)
    [[ $# -lt 2 ]] && { print -u2 -- "care: -s requires an argument"; return 1; }
    system_prompt="$2"
    shift 2
    ;;
    --system=*)
    system_prompt="${1#*=}"
    shift
    ;;
    -m|--model)
    [[ $# -lt 2 ]] && { print -u2 -- "care: -m requires an argument"; return 1; }
    model="$2"
    shift 2
    ;;
    --model=*)
    model="${1#*=}"
    shift
    ;;
    -h|--help)
    cat <<'EOF'
    Usage: care [-s <system-prompt>] [-m <model>] [prompt]
    Runs codex debug prompt-input with all context suppressed (bare minimum):
    - No plugins
    - No AGENTS.md / project docs
    - No skills instructions
    - Isolated HOME and CODEX_HOME
    Options:
    -s, --system <text> Inject a developer_instructions system prompt
    -m, --model <model> Override the model (default: codex default)
    -h, --help Show this help
    EOF
    return 0
    ;;
    *)
    extra_args+=("$1")
    shift
    ;;
    esac
    done
    local -a config_flags=(
    --disable plugins
    -c 'project_doc_max_bytes=0'
    -c 'skills.include_instructions=false'
    )
    if [[ -n "$model" ]]; then
    config_flags+=(-m "$model")
    fi
    if [[ -n "$system_prompt" ]]; then
    # -c value is parsed as TOML, so the string must be TOML-quoted.
    # We use printf %s to safely embed the value inside double quotes,
    # escaping any backslashes and double quotes first.
    local toml_escaped="${system_prompt//\\/\\\\}"
    toml_escaped="${toml_escaped//\"/\\\"}"
    config_flags+=(-c "developer_instructions=\"${toml_escaped}\"")
    fi
    HOME=/tmp/empty-home \
    CODEX_HOME=/tmp/empty-codex-home \
    codex --dangerously-bypass-approvals-and-sandbox \
    "${config_flags[@]}" \
    debug prompt-input \
    "${extra_args[@]}"
    }
    spark() {
    care -m gpt-5.3-codex-spark "$@"
    }
    # =========================
    # cmux expert (cx)
    # =========================
    # One-shot codex exec with:
    # - gpt-5.3-codex-spark model
    # - All context suppressed (bare)
    # - System prompt = cmux SKILL.md + cmux --help
    # - exec (non-interactive) mode
    _cx_system_prompt() {
    local cmux_skill
    cmux_skill=$(curl -fsSL https://raw.githubusercontent.com/manaflow-ai/cmux/main/skills/cmux/SKILL.md 2>/dev/null)
    if [[ -z "$cmux_skill" ]]; then
    print -u2 -- "cx: failed to fetch cmux SKILL.md"
    return 1
    fi
    local cmux_help
    cmux_help=$(cmux --help 2>&1)
    printf '%s\n\n## cmux CLI reference\n\n```\n%s\n```' "$cmux_skill" "$cmux_help"
    }
    # cx — one-shot non-interactive cmux expert
    cx() {
    local system_prompt
    system_prompt=$(_cx_system_prompt) || return 1
    local toml_escaped="${system_prompt//\\/\\\\}"
    toml_escaped="${toml_escaped//\"/\\\"}"
    # Keep real CODEX_HOME for auth; suppress all injected context via flags only.
    # stderr carries the header/tool-call noise; stdout is the final answer only.
    codex --dangerously-bypass-approvals-and-sandbox \
    --disable plugins \
    -c 'project_doc_max_bytes=0' \
    -c 'skills.include_instructions=false' \
    -c 'include_apps_instructions=false' \
    -c 'memories.use_memories=false' \
    -m gpt-5.3-codex-spark \
    -c 'model_reasoning_effort="low"' \
    -c "developer_instructions=\"${toml_escaped}\"" \
    exec \
    "$@" 2>/dev/null
    }
    # cxi — interactive TUI version of cx (same flags, no exec, no stderr suppression)
    cxi() {
    local system_prompt
    system_prompt=$(_cx_system_prompt) || return 1
    local toml_escaped="${system_prompt//\\/\\\\}"
    toml_escaped="${toml_escaped//\"/\\\"}"
    codex --dangerously-bypass-approvals-and-sandbox \
    --disable plugins \
    -c 'project_doc_max_bytes=0' \
    -c 'skills.include_instructions=false' \
    -c 'include_apps_instructions=false' \
    -c 'memories.use_memories=false' \
    -m gpt-5.3-codex-spark \
    -c 'model_reasoning_effort="low"' \
    -c "developer_instructions=\"${toml_escaped}\"" \
    "$@"
    }

    cx-system-prompt.md

    ---
    name: cmux
    description: End-user control of cmux topology and routing (windows, workspaces, panes/surfaces, focus, moves, reorder, identify, trigger flash). Use when automation needs deterministic placement and navigation in a multi-pane cmux layout.
    ---
    # cmux Core Control
    Use this skill to control non-browser cmux topology and routing.
    ## Core Concepts
    - Window: top-level macOS cmux window.
    - Workspace: tab-like group within a window.
    - Pane: split container in a workspace.
    - Surface: a tab within a pane (terminal or browser panel).
    ## Fast Start
    ```bash
    # identify current caller context
    cmux identify --json
    # list topology
    cmux list-windows
    cmux list-workspaces
    cmux list-panes
    cmux list-pane-surfaces --pane pane:1
    # create/focus/move
    cmux new-workspace
    cmux new-split right --panel pane:1
    cmux move-surface --surface surface:7 --pane pane:2 --focus true
    cmux split-off --surface surface:7 right
    cmux reorder-surface --surface surface:7 --before surface:3
    # attention cue
    cmux trigger-flash --surface surface:7
    ```
    ## Settings and Docs
    Use `cmux docs settings` before changing cmux-owned settings. It prints the docs URL, schema URL, raw GitHub resources, cmux.json paths, and reload command.
    ```bash
    cmux docs settings
    cmux settings path
    ```
    cmux-owned settings live in `~/.config/cmux/cmux.json`. Legacy `~/.config/cmux/settings.json` and `~/Library/Application Support/com.cmuxterm.app/settings.json` files are read only as fallback for missing keys. Before editing, copy any existing `cmux.json` file to a timestamped `.bak` next to it so the user can revert. Edit the user file, then reload:
    ```bash
    cmux reload-config
    ```
    `cmux reload-config` reloads BOTH `cmux.json` and Ghostty config (`~/.config/ghostty/config`) and refreshes terminals in place. No app restart needed.
    Use cmux settings for app behavior, sidebar, notifications, browser behavior, automation, workspace colors, and cmux-owned shortcuts. Terminal rendering settings such as font, cursor style, theme, scrollback, background transparency (`background-opacity`), and blur (`background-blur`) belong in Ghostty config at `~/.config/ghostty/config`.
    Open the UI when useful:
    ```bash
    cmux settings
    cmux settings cmux-json
    cmux settings shortcuts
    ```
    ## Handle Model
    - Default output uses short refs: `window:N`, `workspace:N`, `pane:N`, `surface:N`.
    - UUIDs are still accepted as inputs.
    - Request UUID output only when needed: `--id-format uuids|both`.
    ## Deep-Dive References
    | Reference | When to Use |
    |-----------|-------------|
    | [references/handles-and-identify.md](references/handles-and-identify.md) | Handle syntax, self-identify, caller targeting |
    | [references/windows-workspaces.md](references/windows-workspaces.md) | Window/workspace lifecycle and reorder/move |
    | [references/panes-surfaces.md](references/panes-surfaces.md) | Splits, surfaces, move/reorder, focus routing |
    | [references/trigger-flash-and-health.md](references/trigger-flash-and-health.md) | Flash cue and surface health checks |
    | [../cmux-browser/SKILL.md](../cmux-browser/SKILL.md) | Browser automation on surface-backed webviews |
    | [../cmux-markdown/SKILL.md](../cmux-markdown/SKILL.md) | Markdown viewer panel with live file watching |
    ## cmux CLI reference
    ```
    cmux - control cmux via Unix socket
    Usage:
    cmux <path> Open a directory in a new workspace (launches cmux if needed)
    cmux [global-options] <command> [options]
    Handle Inputs:
    Use UUIDs, short refs (window:1/workspace:2/pane:3/surface:4), or indexes where commands accept window, workspace, pane, or surface inputs.
    `tab-action` also accepts `tab:<n>` in addition to `surface:<n>`.
    Output defaults to refs; pass --id-format uuids or --id-format both to include UUIDs.
    Socket Auth:
    --password takes precedence, then CMUX_SOCKET_PASSWORD env var, then password saved in Settings.
    Agent Help:
    To change cmux settings, run `cmux docs settings` and `cmux settings path`; to add Dock controls, run `cmux docs dock`.
    Back up any existing cmux.json file to a timestamped .bak copy before editing.
    Use printed curl commands to fetch the latest docs/schema, and prefer Ghostty config for terminal behavior Ghostty already supports.
    Commands:
    welcome
    docs [settings|shortcuts|api|browser|agents|dock]
    settings [open [target]|path|docs|<target>]
    config <doctor|check|validate|path|paths|docs|documentation|reload>
    shortcuts
    disable-browser | enable-browser | browser-status
    restore-session
    feedback [--email <email> --body <text> [--image <path> ...]]
    feed tui|clear
    themes [list|set|clear]
    claude-teams [claude-args...]
    omo [opencode-args...]
    omx [omx-args...]
    omc [omc-args...]
    hooks setup|uninstall [--agent <name>]
    hooks <agent> <install|uninstall|event> [options; opencode supports --project]
    hooks feed --source <agent> [--event <event>]
    ping
    version
    capabilities
    events [--after <seq>] [--cursor-file <path>] [--name <event>] [--category <category>] [--reconnect] [--limit <n>] [--no-ack] [--no-heartbeat]
    auth <status|login|logout>
    login | logout (aliases for auth login/logout)
    vm <new|ls|rm|exec|shell|ssh> [args...] (alias: cloud)
    rpc <method> [json-params]
    identify [--workspace <id|ref|index>] [--surface <id|ref|index>] [--no-caller]
    list-windows
    current-window
    new-window
    focus-window --window <id>
    close-window --window <id>
    move-workspace-to-window --workspace <id|ref> --window <id|ref>
    reorder-workspace --workspace <id|ref|index> (--index <n> | --before <id|ref|index> | --after <id|ref|index>) [--window <id|ref|index>]
    workspace-action --action <name> [--workspace <id|ref|index>] [--title <text>] [--color <name|#hex>] [--description <text>]
    move-tab-to-new-workspace [--tab <id|ref|index>] [--surface <id|ref|index>] [--workspace <id|ref|index>] [--title <text>] [--focus <true|false>]
    list-workspaces
    new-workspace [--name <title>] [--description <text>] [--cwd <path>] [--command <text>] [--layout <json>] [--focus <true|false>]
    ssh <destination> [--name <title>] [--port <n>] [--identity <path>] [--ssh-option <opt>] [--no-focus] [-- <remote-command-args>]
    remote-daemon-status [--os <darwin|linux>] [--arch <arm64|amd64>]
    new-split <left|right|up|down> [--workspace <id|ref>] [--surface <id|ref>] [--panel <id|ref>] [--focus <true|false>]
    list-panes [--workspace <id|ref>]
    list-pane-surfaces [--workspace <id|ref>] [--pane <id|ref>]
    tree [--all] [--workspace <id|ref|index>]
    top [--all] [--workspace <id|ref|index>] [--processes]
    focus-pane --pane <id|ref> [--workspace <id|ref>]
    new-pane [--type <terminal|browser>] [--direction <left|right|up|down>] [--workspace <id|ref>] [--url <url>] [--focus <true|false>]
    new-surface [--type <terminal|browser>] [--pane <id|ref>] [--workspace <id|ref>] [--url <url>] [--focus <true|false>]
    close-surface [--surface <id|ref>] [--workspace <id|ref>]
    move-surface --surface <id|ref|index> [--pane <id|ref|index>] [--workspace <id|ref|index>] [--window <id|ref|index>] [--before <id|ref|index>] [--after <id|ref|index>] [--index <n>] [--focus <true|false>]
    split-off --surface <id|ref|index> <left|right|up|down> [--workspace <id|ref|index>] [--focus <true|false>]
    reorder-surface --surface <id|ref|index> (--index <n> | --before <id|ref|index> | --after <id|ref|index>) [--focus <true|false>]
    tab-action --action <name> [--tab <id|ref|index>] [--surface <id|ref|index>] [--workspace <id|ref|index>] [--title <text>] [--url <url>] [--focus <true|false>]
    rename-tab [--workspace <id|ref>] [--tab <id|ref>] [--surface <id|ref>] <title>
    drag-surface-to-split --surface <id|ref|index> <left|right|up|down> [--workspace <id|ref|index>] [--focus <true|false>]
    refresh-surfaces
    reload-config
    surface-health [--workspace <id|ref>]
    debug-terminals
    trigger-flash [--workspace <id|ref>] [--surface <id|ref>]
    list-panels [--workspace <id|ref>]
    focus-panel --panel <id|ref> [--workspace <id|ref>]
    close-workspace --workspace <id|ref>
    select-workspace --workspace <id|ref>
    rename-workspace [--workspace <id|ref>] <title>
    rename-window [--workspace <id|ref>] <title>
    current-workspace
    read-screen [--workspace <id|ref>] [--surface <id|ref>] [--scrollback] [--lines <n>]
    send [--workspace <id|ref>] [--surface <id|ref>] <text>
    send-key [--workspace <id|ref>] [--surface <id|ref>] <key>
    send-panel --panel <id|ref> [--workspace <id|ref>] <text>
    send-key-panel --panel <id|ref> [--workspace <id|ref>] <key>
    notify --title <text> [--subtitle <text>] [--body <text>] [--workspace <id|ref>] [--surface <id|ref>]
    list-notifications
    clear-notifications
    set-status <key> <value> [--workspace <id|ref>] [--icon <name>] [--color <#hex>]
    clear-status <key> [--workspace <id|ref>]
    list-status [--workspace <id|ref>]
    set-progress <0.0-1.0> [--label <text>] [--workspace <id|ref>]
    clear-progress [--workspace <id|ref>]
    log [--level <level>] [--source <name>] [--workspace <id|ref>] <message>
    clear-log [--workspace <id|ref>]
    list-log [--workspace <id|ref>] [--limit <n>]
    sidebar-state [--workspace <id|ref>]
    set-app-focus <active|inactive|clear>
    simulate-app-active
    # tmux compatibility commands
    capture-pane [--workspace <id|ref>] [--surface <id|ref>] [--scrollback] [--lines <n>]
    resize-pane --pane <id|ref> [--workspace <id|ref>] (-L|-R|-U|-D) [--amount <n>]
    pipe-pane --command <shell-command> [--workspace <id|ref>] [--surface <id|ref>]
    wait-for [-S|--signal] <name> [--timeout <seconds>]
    swap-pane --pane <id|ref> --target-pane <id|ref> [--workspace <id|ref>] [--focus <true|false>]
    break-pane [--workspace <id|ref>] [--pane <id|ref>] [--surface <id|ref>] [--focus <true|false>] [--no-focus]
    join-pane --target-pane <id|ref> [--workspace <id|ref>] [--pane <id|ref>] [--surface <id|ref>] [--focus <true|false>] [--no-focus]
    next-window | previous-window | last-window
    last-pane [--workspace <id|ref>]
    find-window [--content] [--select] <query>
    clear-history [--workspace <id|ref>] [--surface <id|ref>]
    set-hook [--list] [--unset <event>] | <event> <command>
    popup
    bind-key | unbind-key | copy-mode
    set-buffer [--name <name>] <text>
    list-buffers
    paste-buffer [--name <name>] [--workspace <id|ref>] [--surface <id|ref>]
    respawn-pane [--workspace <id|ref>] [--surface <id|ref>] [--command <cmd>]
    display-message [-p|--print] <text>
    markdown [open] <path> [--focus <true|false>] (open markdown file in formatted viewer panel with live reload)
    browser [--surface <id|ref|index> | <surface>] <subcommand> ...
    browser disable | enable | status
    browser open [url] [--focus <true|false>] (create browser split in caller's workspace; if surface supplied, behaves like navigate)
    browser open-split [url]
    browser goto|navigate <url> [--snapshot-after]
    browser back|forward|reload [--snapshot-after]
    browser url|get-url
    browser snapshot [--interactive|-i] [--cursor] [--compact] [--max-depth <n>] [--selector <css>]
    browser eval <script>
    browser wait [--selector <css>] [--text <text>] [--url-contains <text>] [--load-state <interactive|complete>] [--function <js>] [--timeout-ms <ms>]
    browser click|dblclick|hover|focus|check|uncheck|scroll-into-view <selector> [--snapshot-after]
    browser type <selector> <text> [--snapshot-after]
    browser fill <selector> [text] [--snapshot-after] (empty text clears input)
    browser press|keydown|keyup <key> [--snapshot-after]
    browser select <selector> <value> [--snapshot-after]
    browser scroll [--selector <css>] [--dx <n>] [--dy <n>] [--snapshot-after]
    browser screenshot [--out <path>] [--json]
    browser get <url|title|text|html|value|attr|count|box|styles> [...]
    browser is <visible|enabled|checked> <selector>
    browser find <role|text|label|placeholder|alt|title|testid|first|last|nth> ...
    browser frame <selector|main>
    browser dialog <accept|dismiss> [text]
    browser download [wait] [--path <path>] [--timeout-ms <ms>]
    browser profiles <list|add|rename|clear|delete> [...]
    browser profiles clear <profile|--all> [--force]
    browser import [...]
    browser cookies <get|set|clear> [...]
    browser storage <local|session> <get|set|clear> [...]
    browser tab <new|list|switch|close|<index>> [...]
    browser console <list|clear>
    browser errors <list|clear>
    browser highlight <selector>
    browser state <save|load> <path>
    browser addinitscript <script>
    browser addscript <script>
    browser addstyle <css>
    browser identify [--surface <id|ref|index>]
    help
    Environment:
    CMUX_WORKSPACE_ID Auto-set in cmux terminals. Used as default --workspace for
    ALL commands (send, list-panels, new-split, notify, etc.).
    CMUX_TAB_ID Optional alias used by `tab-action`/`rename-tab` as default --tab.
    CMUX_SURFACE_ID Auto-set in cmux terminals. Used as default --surface.
    CMUX_SOCKET_PATH Override the Unix socket path. Without this, the CLI defaults
    to ~/Library/Application Support/cmux/cmux.sock and auto-discovers tagged/debug sockets.
    ```
    Share