{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/philschmid-de/2025-04-17-openai-codex-cli-how-does-it-work/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "OpenAI Codex is a open source CLI released with OpenAI o3/o4-mini to be a \"chat-driven development\" tool. It allows developers to use AI models via API directly in their terminal to perform coding tasks. Unlike a simple chatbot, it can read files, write files (via patches), execute shell commands (often sandboxed), and iterate based on the results and user feedback.\n\n*Note: This overview was generated with Gemini 2.5 Pro and updated collaboratively iterated on with Gemini 2.5 Pro and myself.*\n\n## Core Components & Workflow\n\n### User Interface (UI)\n\n- The interactive terminal UI is built using `ink` and `react`, offering a richer experience than plain text. Key components reside in [`src/components/`](https://github.com/openai/codex/tree/main/codex-cli/src/components/), particularly within [`src/components/chat/`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/).\n- The application entry point is [`src/cli.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx) (using `meow` for argument parsing), which sets up the main [`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx) component via [`src/app.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx).\n- [`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx) manages the overall display including history, input prompts, loading states, and overlays.\n- User input is handled by [`TerminalChatInput`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-input.tsx) (or [`TerminalChatNewInput`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-new-input.tsx)), supporting command history and slash commands.\n- The conversation history is displayed by [`TerminalMessageHistory`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-message-history.tsx), using components like [`TerminalChatResponseItem`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-response-item.tsx) to render different message types.\n\n### Agent Loop\n\n- The core logic resides in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts).\n- The `AgentLoop` class manages the interaction cycle with the OpenAI API.\n- It takes the user's input, combines it with conversation history and instructions, and sends it to the model.\n- It uses the `openai` Node.js library (v4+) and specifically calls `openai.responses.create`, indicating use of the `/responses` endpoint which supports streaming and tool use.\n\n### Model Interaction\n\n- The `AgentLoop` sends the context (history, instructions, user input) to the specified model (default `o4-mini`, configurable via `--model` or config file).\n- It requests a *streaming* response.\n- It handles different response item types (`message`, `function_call`, `function_call_output`, `reasoning`).\n- [`src/utils/model-utils.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/model-utils.ts) handles fetching available models and checking compatibility.\n\n### Tools & Execution\n\n- The primary \"tool\" defined is `shell` (or `container.exec`), allowing the model to request shell command execution. See the `tools` array in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L512).\n\n#### Command Execution\n\n- When the model emits a `function_call` for `shell`, the `AgentLoop` invokes `handleExecCommand` ([`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)).\n- This function checks the approval policy (`suggest`, `auto-edit`, `full-auto`).\n- [`src/approvals.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts) (`canAutoApprove`) determines if the command is known-safe or needs user confirmation based on the policy.\n- If confirmation is needed, the UI ([`TerminalChatCommandReview`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx)) prompts the user.\n- If approved (or auto-approved), the command is executed via [`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts).\n\n#### Sandboxing\n\n- The execution logic in `handleExecCommand` decides *how* to run the command based on the approval policy and safety assessment.\n- `full-auto` mode implies sandboxing.\n- [`src/utils/agent/sandbox/`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/) contains the sandboxing implementations:\n  - [`macos-seatbelt.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/macos-seatbelt.ts): Uses macOS's `sandbox-exec` to restrict file system access and block network calls (`READ_ONLY_SEATBELT_POLICY`). Writable paths are whitelisted.\n  - [`raw-exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/raw-exec.ts): Executes commands directly without sandboxing (used when sandboxing isn't needed or available).\n  - Linux: The [`README.md`](https://github.com/openai/codex/blob/main/codex-cli/README.md), [`Dockerfile`](https://github.com/openai/codex/blob/main/codex-cli/Dockerfile), and [`scripts/`](https://github.com/openai/codex/tree/main/codex-cli/scripts/) indicate a Docker-based approach. The CLI runs inside a minimal container where [`scripts/init_firewall.sh`](https://github.com/openai/codex/tree/main/codex-cli/scripts/init_firewall.sh) uses `iptables`/`ipset` to restrict network access only to the OpenAI API. The user's project directory is mounted into the container.\n\n#### File Patching (`apply_patch`)\n\n- The model is instructed (via the system prompt in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts)) to use a specific format like `{\"cmd\":[\"apply_patch\",\"*** Begin Patch...\"]}` when it wants to edit files.\n- `handleExecCommand` detects this pattern.\n- Instead of running `apply_patch` as a shell command, it uses `execApplyPatch` ([`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts)), which calls `process_patch` from [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts).\n- [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts) parses the patch format and uses Node.js `fs` calls to modify files directly on the host system (or within the container on Linux).\n- [`parse-apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/parse-apply-patch.ts) (likely used by the UI) helps render diffs for user review.\n\n### Prompts & Context Awareness\n\n- **System Prompt:** A long, detailed system prompt is hardcoded as `prefix` within [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L1021). This tells the model about its role as the Codex CLI, its capabilities (shell, patching), constraints (sandboxing), and coding guidelines.\n- **User Instructions:** Instructions are gathered from both global (`~/.codex/instructions.md`) and project-specific (`codex.md` or similar, discovered via logic in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)) files. These combined instructions are prepended to the conversation history sent to the model.\n- **Conversation History:** The `items` array (containing `ResponseItem` objects like user messages, assistant messages, tool calls, tool outputs) is passed back to the model on each turn, providing conversational context. [`src/utils/approximate-tokens-used.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/approximate-tokens-used.ts) estimates context window usage.\n- **File Context (Standard Mode):** The agent doesn't automatically read project files. It gains file context only when the model explicitly requests to read a file (e.g., via `cat`) or when file content appears in the output of a previous command (e.g., `git diff`).\n- **File Context (Experimental `--full-context` Mode):** This mode utilizes a distinct flow (see [`src/cli_singlepass.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli_singlepass.tsx), [`src/utils/singlepass/`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/)). It involves:\n  - Walking the directory, reading, and caching files via [`src/utils/singlepass/context_files.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context_files.ts).\n  - Formatting the prompt, directory structure, and file contents into a single large request using [`src/utils/singlepass/context.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context.ts).\n  - Expecting the model to return all file changes (creations, updates, deletes, moves) in a specific Zod schema defined in [`src/utils/singlepass/file_ops.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/file_ops.ts).\n- **Configuration:** Stores default model, approval mode settings, etc. Managed by [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts), loads from `~/.codex/config.yaml` (or `.yml`/`.json`) (not in repo).\n\n## Step-by-Step Manual Walkthrough (Simulating the CLI)\n\nLet's imagine the user runs: `codex \"Refactor utils.ts to use arrow functions\"` in a directory `/home/user/myproject`.\n\n1.  **Initialization ([`cli.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx), [`app.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx)):**\n\n    - Parse arguments: Prompt is \"Refactor...\", model is default (`o4-mini`), approval mode is default (`suggest`).\n    - Load config (`loadConfig` in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)): Read `~/.codex/config.yaml` and `~/.codex/instructions.md`.\n    - Discover and load project docs (`loadProjectDoc` in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)): Find `/home/user/myproject/codex.md` and read its content.\n    - Combine instructions: Merge user instructions and project docs.\n    - Check Git status (`checkInGit` in [`src/utils/check-in-git.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/check-in-git.ts)): Confirm `/home/user/myproject` is a Git repo.\n    - Render the main UI ([`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx)).\n2.  **First API Call (`AgentLoop.run` in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts)):**\n\n    - Create initial input: `[{ role: \"user\", content: [{ type: \"input_text\", text: \"Refactor...\" }] }]`.\n    - Construct API request payload: Include system prompt (from `prefix`), combined instructions, and the user input message. Set `model: \"o4-mini\"`, `stream: true`, `tools: [...]`. No `previous_response_id`.\n    - Send request: Call `openai.responses.create(...)` (using the `openai` library). UI shows \"Thinking...\".\n3.  **Model Response (Stream):**\n\n    - Assume the model decides it needs to read the file first.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"function_call\", name: \"shell\", arguments: '{\"cmd\": [\"cat\", \"utils.ts\"]}', call_id: \"call_1\" }`\n    - Stream event 2: `response.completed` with `output: [...]` containing the same function call, `id: \"resp_1\"`.\n    - Agent receives the function call. `onLastResponseId` is called with `\"resp_1\"`.\n4.  **Tool Call Handling (`handleExecCommand` in [`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)):**\n\n    - Parse arguments: `cmd = [\"cat\", \"utils.ts\"]`.\n    - Check approval: `canAutoApprove([\"cat\", \"utils.ts\"], \"suggest\", [\"/home/user/myproject\"])` (in [`src/approvals.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts)) -> returns `{ type: \"auto-approve\", reason: \"View file contents\", group: \"Reading files\", runInSandbox: false }`.\n    - Execute command (`execCommand` in [`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)): Run `cat utils.ts` directly (no sandbox needed for safe commands). *Note: Assuming `utils.ts` exists at the root for this example; in reality, the model might need to specify a path like `src/utils.ts`.*\n    - Simulate result: `stdout = \"/* content of utils.ts */\", stderr = \"\", exitCode = 0`.\n5.  **Second API Call (`AgentLoop.run` continues):**\n\n    - Format tool result: Create a `function_call_output` item like `{ type: \"function_call_output\", call_id: \"call_1\", output: '{\"output\": \"/* content ... */\", \"metadata\": {\"exit_code\": 0, ...}}' }`.\n    - Construct API request payload: Include system prompt, combined instructions, the *entire history so far* (user message, assistant function call request, function call output), set `previous_response_id: \"resp_1\"`.\n    - Send request. UI shows \"Thinking...\".\n6.  **Model Response (Stream):**\n\n    - Assume model generates the refactored code and decides to apply it.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"function_call\", name: \"shell\", arguments: '{\"cmd\": [\"apply_patch\", \"*** Begin Patch\\n*** Update File: utils.ts\\n@@ ... -old +new ...\\n*** End Patch\"]}', call_id: \"call_2\" }`.\n    - Stream event 2: `response.completed` with `output: [...]` containing the patch function call, `id: \"resp_2\"`.\n    - Agent receives the patch function call. `onLastResponseId` is called with `\"resp_2\"`.\n7.  **Tool Call Handling (Patch):**\n\n    - Parse arguments: Identify `apply_patch` and extract the patch text.\n    - Check approval: `canAutoApprove([\"apply_patch\", \"...\"], \"suggest\", [\"/home/user/myproject\"])`. Since policy is `suggest`, this returns `{ type: \"ask-user\", applyPatch: { patch: \"...\" } }`.\n    - Request confirmation (`requestConfirmation`): The UI ([`TerminalChatCommandReview`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx)) displays the patch diff and asks \"Allow command? \\[y/N/e/a\\]\".\n    - User reviews and presses 'y'. `submitConfirmation` is called with `{ decision: ReviewDecision.YES }`.\n    - Execute patch (`execApplyPatch` in [`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts) -> `process_patch` in [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts)): Reads `utils.ts`, applies the diff logic, and writes the modified content back using Node.js `fs.writeFileSync`.\n    - Simulate result: `stdout = \"Done!\", stderr = \"\", exitCode = 0`.\n8.  **Third API Call:**\n\n    - Format tool result: Create `function_call_output` item for the patch, `{ call_id: \"call_2\", output: '{\"output\": \"Done!\", ...}' }`.\n    - Construct API request: Include history + patch result, `previous_response_id: \"resp_2\"`.\n    - Send request.\n9.  **Model Response (Final):**\n\n    - Assume model confirms the refactoring is done.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"message\", role: \"assistant\", content: [{ type: \"output_text\", text: \"OK, I've refactored utils.ts to use arrow functions.\" }] }`.\n    - Stream event 2: `response.completed`, `id: \"resp_3\"`.\n    - Agent receives the message. `onLastResponseId` called with `\"resp_3\"`.\n    - No more tool calls. The loop finishes for this turn. UI stops showing \"Thinking...\".\n10. **User Interaction:**\n\n    - The user sees the final message and the updated prompt, ready for the next command. The file `utils.ts` on their disk has been modified.\n",
  "authors": [],
  "captured_at": "2026-09-27T19:29:15.293681927+00:00",
  "category": "programming",
  "content_html": "<p>OpenAI Codex is a open source CLI released with OpenAI o3/o4-mini to be a &quot;chat-driven development&quot; tool. It allows developers to use AI models via API directly in their terminal to perform coding tasks. Unlike a simple chatbot, it can read files, write files (via patches), execute shell commands (often sandboxed), and iterate based on the results and user feedback.</p>\n<p><em>Note: This overview was generated with Gemini 2.5 Pro and updated collaboratively iterated on with Gemini 2.5 Pro and myself.</em></p>\n<h2>Core Components &amp; Workflow</h2>\n<h3>User Interface (UI)</h3>\n<ul>\n<li>The interactive terminal UI is built using <code>ink</code> and <code>react</code>, offering a richer experience than plain text. Key components reside in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/\"><code>src/components/</code></a>, particularly within <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/\"><code>src/components/chat/</code></a>.</li>\n<li>The application entry point is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx\"><code>src/cli.tsx</code></a> (using <code>meow</code> for argument parsing), which sets up the main <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx\"><code>TerminalChat</code></a> component via <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx\"><code>src/app.tsx</code></a>.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx\"><code>TerminalChat</code></a> manages the overall display including history, input prompts, loading states, and overlays.</li>\n<li>User input is handled by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-input.tsx\"><code>TerminalChatInput</code></a> (or <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-new-input.tsx\"><code>TerminalChatNewInput</code></a>), supporting command history and slash commands.</li>\n<li>The conversation history is displayed by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-message-history.tsx\"><code>TerminalMessageHistory</code></a>, using components like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-response-item.tsx\"><code>TerminalChatResponseItem</code></a> to render different message types.</li>\n</ul>\n<h3>Agent Loop</h3>\n<ul>\n<li>The core logic resides in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts\"><code>src/utils/agent/agent-loop.ts</code></a>.</li>\n<li>The <code>AgentLoop</code> class manages the interaction cycle with the OpenAI API.</li>\n<li>It takes the user's input, combines it with conversation history and instructions, and sends it to the model.</li>\n<li>It uses the <code>openai</code> Node.js library (v4+) and specifically calls <code>openai.responses.create</code>, indicating use of the <code>/responses</code> endpoint which supports streaming and tool use.</li>\n</ul>\n<h3>Model Interaction</h3>\n<ul>\n<li>The <code>AgentLoop</code> sends the context (history, instructions, user input) to the specified model (default <code>o4-mini</code>, configurable via <code>--model</code> or config file).</li>\n<li>It requests a <em>streaming</em> response.</li>\n<li>It handles different response item types (<code>message</code>, <code>function_call</code>, <code>function_call_output</code>, <code>reasoning</code>).</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/model-utils.ts\"><code>src/utils/model-utils.ts</code></a> handles fetching available models and checking compatibility.</li>\n</ul>\n<h3>Tools &amp; Execution</h3>\n<ul>\n<li>The primary &quot;tool&quot; defined is <code>shell</code> (or <code>container.exec</code>), allowing the model to request shell command execution. See the <code>tools</code> array in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L512\"><code>src/utils/agent/agent-loop.ts</code></a>.</li>\n</ul>\n<h4>Command Execution</h4>\n<ul>\n<li>When the model emits a <code>function_call</code> for <code>shell</code>, the <code>AgentLoop</code> invokes <code>handleExecCommand</code> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts\"><code>src/utils/agent/handle-exec-command.ts</code></a>).</li>\n<li>This function checks the approval policy (<code>suggest</code>, <code>auto-edit</code>, <code>full-auto</code>).</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts\"><code>src/approvals.ts</code></a> (<code>canAutoApprove</code>) determines if the command is known-safe or needs user confirmation based on the policy.</li>\n<li>If confirmation is needed, the UI (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx\"><code>TerminalChatCommandReview</code></a>) prompts the user.</li>\n<li>If approved (or auto-approved), the command is executed via <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts\"><code>src/utils/agent/exec.ts</code></a>.</li>\n</ul>\n<h4>Sandboxing</h4>\n<ul>\n<li>The execution logic in <code>handleExecCommand</code> decides <em>how</em> to run the command based on the approval policy and safety assessment.</li>\n<li><code>full-auto</code> mode implies sandboxing.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/\"><code>src/utils/agent/sandbox/</code></a> contains the sandboxing implementations:\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/macos-seatbelt.ts\"><code>macos-seatbelt.ts</code></a>: Uses macOS's <code>sandbox-exec</code> to restrict file system access and block network calls (<code>READ_ONLY_SEATBELT_POLICY</code>). Writable paths are whitelisted.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/raw-exec.ts\"><code>raw-exec.ts</code></a>: Executes commands directly without sandboxing (used when sandboxing isn't needed or available).</li>\n<li>Linux: The <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/blob/main/codex-cli/README.md\"><code>README.md</code></a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/blob/main/codex-cli/Dockerfile\"><code>Dockerfile</code></a>, and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/scripts/\"><code>scripts/</code></a> indicate a Docker-based approach. The CLI runs inside a minimal container where <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/scripts/init_firewall.sh\"><code>scripts/init_firewall.sh</code></a> uses <code>iptables</code>/<code>ipset</code> to restrict network access only to the OpenAI API. The user's project directory is mounted into the container.</li>\n</ul>\n</li>\n</ul>\n<h4>File Patching (<code>apply_patch</code>)</h4>\n<ul>\n<li>The model is instructed (via the system prompt in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts\"><code>src/utils/agent/agent-loop.ts</code></a>) to use a specific format like <code>{&quot;cmd&quot;:[&quot;apply_patch&quot;,&quot;*** Begin Patch...&quot;]}</code> when it wants to edit files.</li>\n<li><code>handleExecCommand</code> detects this pattern.</li>\n<li>Instead of running <code>apply_patch</code> as a shell command, it uses <code>execApplyPatch</code> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts\"><code>src/utils/agent/exec.ts</code></a>), which calls <code>process_patch</code> from <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts\"><code>src/utils/agent/apply-patch.ts</code></a>.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts\"><code>src/utils/agent/apply-patch.ts</code></a> parses the patch format and uses Node.js <code>fs</code> calls to modify files directly on the host system (or within the container on Linux).</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/parse-apply-patch.ts\"><code>parse-apply-patch.ts</code></a> (likely used by the UI) helps render diffs for user review.</li>\n</ul>\n<h3>Prompts &amp; Context Awareness</h3>\n<ul>\n<li><strong>System Prompt:</strong> A long, detailed system prompt is hardcoded as <code>prefix</code> within <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L1021\"><code>src/utils/agent/agent-loop.ts</code></a>. This tells the model about its role as the Codex CLI, its capabilities (shell, patching), constraints (sandboxing), and coding guidelines.</li>\n<li><strong>User Instructions:</strong> Instructions are gathered from both global (<code>~/.codex/instructions.md</code>) and project-specific (<code>codex.md</code> or similar, discovered via logic in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts\"><code>src/utils/config.ts</code></a>) files. These combined instructions are prepended to the conversation history sent to the model.</li>\n<li><strong>Conversation History:</strong> The <code>items</code> array (containing <code>ResponseItem</code> objects like user messages, assistant messages, tool calls, tool outputs) is passed back to the model on each turn, providing conversational context. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/approximate-tokens-used.ts\"><code>src/utils/approximate-tokens-used.ts</code></a> estimates context window usage.</li>\n<li><strong>File Context (Standard Mode):</strong> The agent doesn't automatically read project files. It gains file context only when the model explicitly requests to read a file (e.g., via <code>cat</code>) or when file content appears in the output of a previous command (e.g., <code>git diff</code>).</li>\n<li><strong>File Context (Experimental <code>--full-context</code> Mode):</strong> This mode utilizes a distinct flow (see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/cli_singlepass.tsx\"><code>src/cli_singlepass.tsx</code></a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/\"><code>src/utils/singlepass/</code></a>). It involves:\n<ul>\n<li>Walking the directory, reading, and caching files via <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context_files.ts\"><code>src/utils/singlepass/context_files.ts</code></a>.</li>\n<li>Formatting the prompt, directory structure, and file contents into a single large request using <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context.ts\"><code>src/utils/singlepass/context.ts</code></a>.</li>\n<li>Expecting the model to return all file changes (creations, updates, deletes, moves) in a specific Zod schema defined in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/file_ops.ts\"><code>src/utils/singlepass/file_ops.ts</code></a>.</li>\n</ul>\n</li>\n<li><strong>Configuration:</strong> Stores default model, approval mode settings, etc. Managed by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts\"><code>src/utils/config.ts</code></a>, loads from <code>~/.codex/config.yaml</code> (or <code>.yml</code>/<code>.json</code>) (not in repo).</li>\n</ul>\n<h2>Step-by-Step Manual Walkthrough (Simulating the CLI)</h2>\n<p>Let's imagine the user runs: <code>codex &quot;Refactor utils.ts to use arrow functions&quot;</code> in a directory <code>/home/user/myproject</code>.</p>\n<ol>\n<li>\n<p><strong>Initialization (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx\"><code>cli.tsx</code></a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx\"><code>app.tsx</code></a>):</strong></p>\n<ul>\n<li>Parse arguments: Prompt is &quot;Refactor...&quot;, model is default (<code>o4-mini</code>), approval mode is default (<code>suggest</code>).</li>\n<li>Load config (<code>loadConfig</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts\"><code>src/utils/config.ts</code></a>): Read <code>~/.codex/config.yaml</code> and <code>~/.codex/instructions.md</code>.</li>\n<li>Discover and load project docs (<code>loadProjectDoc</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts\"><code>src/utils/config.ts</code></a>): Find <code>/home/user/myproject/codex.md</code> and read its content.</li>\n<li>Combine instructions: Merge user instructions and project docs.</li>\n<li>Check Git status (<code>checkInGit</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/check-in-git.ts\"><code>src/utils/check-in-git.ts</code></a>): Confirm <code>/home/user/myproject</code> is a Git repo.</li>\n<li>Render the main UI (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx\"><code>TerminalChat</code></a>).</li>\n</ul>\n</li>\n<li>\n<p><strong>First API Call (<code>AgentLoop.run</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts\"><code>src/utils/agent/agent-loop.ts</code></a>):</strong></p>\n<ul>\n<li>Create initial input: <code>[{ role: &quot;user&quot;, content: [{ type: &quot;input_text&quot;, text: &quot;Refactor...&quot; }] }]</code>.</li>\n<li>Construct API request payload: Include system prompt (from <code>prefix</code>), combined instructions, and the user input message. Set <code>model: &quot;o4-mini&quot;</code>, <code>stream: true</code>, <code>tools: [...]</code>. No <code>previous_response_id</code>.</li>\n<li>Send request: Call <code>openai.responses.create(...)</code> (using the <code>openai</code> library). UI shows &quot;Thinking...&quot;.</li>\n</ul>\n</li>\n<li>\n<p><strong>Model Response (Stream):</strong></p>\n<ul>\n<li>Assume the model decides it needs to read the file first.</li>\n<li>Stream event 1: <code>response.output_item.done</code> with <code>item: { type: &quot;function_call&quot;, name: &quot;shell&quot;, arguments: '{&quot;cmd&quot;: [&quot;cat&quot;, &quot;utils.ts&quot;]}', call_id: &quot;call_1&quot; }</code></li>\n<li>Stream event 2: <code>response.completed</code> with <code>output: [...]</code> containing the same function call, <code>id: &quot;resp_1&quot;</code>.</li>\n<li>Agent receives the function call. <code>onLastResponseId</code> is called with <code>&quot;resp_1&quot;</code>.</li>\n</ul>\n</li>\n<li>\n<p><strong>Tool Call Handling (<code>handleExecCommand</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts\"><code>src/utils/agent/handle-exec-command.ts</code></a>):</strong></p>\n<ul>\n<li>Parse arguments: <code>cmd = [&quot;cat&quot;, &quot;utils.ts&quot;]</code>.</li>\n<li>Check approval: <code>canAutoApprove([&quot;cat&quot;, &quot;utils.ts&quot;], &quot;suggest&quot;, [&quot;/home/user/myproject&quot;])</code> (in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts\"><code>src/approvals.ts</code></a>) -&gt; returns <code>{ type: &quot;auto-approve&quot;, reason: &quot;View file contents&quot;, group: &quot;Reading files&quot;, runInSandbox: false }</code>.</li>\n<li>Execute command (<code>execCommand</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts\"><code>src/utils/agent/handle-exec-command.ts</code></a>): Run <code>cat utils.ts</code> directly (no sandbox needed for safe commands). <em>Note: Assuming <code>utils.ts</code> exists at the root for this example; in reality, the model might need to specify a path like <code>src/utils.ts</code>.</em></li>\n<li>Simulate result: <code>stdout = &quot;/* content of utils.ts */&quot;, stderr = &quot;&quot;, exitCode = 0</code>.</li>\n</ul>\n</li>\n<li>\n<p><strong>Second API Call (<code>AgentLoop.run</code> continues):</strong></p>\n<ul>\n<li>Format tool result: Create a <code>function_call_output</code> item like <code>{ type: &quot;function_call_output&quot;, call_id: &quot;call_1&quot;, output: '{&quot;output&quot;: &quot;/* content ... */&quot;, &quot;metadata&quot;: {&quot;exit_code&quot;: 0, ...}}' }</code>.</li>\n<li>Construct API request payload: Include system prompt, combined instructions, the <em>entire history so far</em> (user message, assistant function call request, function call output), set <code>previous_response_id: &quot;resp_1&quot;</code>.</li>\n<li>Send request. UI shows &quot;Thinking...&quot;.</li>\n</ul>\n</li>\n<li>\n<p><strong>Model Response (Stream):</strong></p>\n<ul>\n<li>Assume model generates the refactored code and decides to apply it.</li>\n<li>Stream event 1: <code>response.output_item.done</code> with <code>item: { type: &quot;function_call&quot;, name: &quot;shell&quot;, arguments: '{&quot;cmd&quot;: [&quot;apply_patch&quot;, &quot;*** Begin Patch\\n*** Update File: utils.ts\\n@@ ... -old +new ...\\n*** End Patch&quot;]}', call_id: &quot;call_2&quot; }</code>.</li>\n<li>Stream event 2: <code>response.completed</code> with <code>output: [...]</code> containing the patch function call, <code>id: &quot;resp_2&quot;</code>.</li>\n<li>Agent receives the patch function call. <code>onLastResponseId</code> is called with <code>&quot;resp_2&quot;</code>.</li>\n</ul>\n</li>\n<li>\n<p><strong>Tool Call Handling (Patch):</strong></p>\n<ul>\n<li>Parse arguments: Identify <code>apply_patch</code> and extract the patch text.</li>\n<li>Check approval: <code>canAutoApprove([&quot;apply_patch&quot;, &quot;...&quot;], &quot;suggest&quot;, [&quot;/home/user/myproject&quot;])</code>. Since policy is <code>suggest</code>, this returns <code>{ type: &quot;ask-user&quot;, applyPatch: { patch: &quot;...&quot; } }</code>.</li>\n<li>Request confirmation (<code>requestConfirmation</code>): The UI (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx\"><code>TerminalChatCommandReview</code></a>) displays the patch diff and asks &quot;Allow command? [y/N/e/a]&quot;.</li>\n<li>User reviews and presses 'y'. <code>submitConfirmation</code> is called with <code>{ decision: ReviewDecision.YES }</code>.</li>\n<li>Execute patch (<code>execApplyPatch</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts\"><code>src/utils/agent/exec.ts</code></a> -&gt; <code>process_patch</code> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts\"><code>src/utils/agent/apply-patch.ts</code></a>): Reads <code>utils.ts</code>, applies the diff logic, and writes the modified content back using Node.js <code>fs.writeFileSync</code>.</li>\n<li>Simulate result: <code>stdout = &quot;Done!&quot;, stderr = &quot;&quot;, exitCode = 0</code>.</li>\n</ul>\n</li>\n<li>\n<p><strong>Third API Call:</strong></p>\n<ul>\n<li>Format tool result: Create <code>function_call_output</code> item for the patch, <code>{ call_id: &quot;call_2&quot;, output: '{&quot;output&quot;: &quot;Done!&quot;, ...}' }</code>.</li>\n<li>Construct API request: Include history + patch result, <code>previous_response_id: &quot;resp_2&quot;</code>.</li>\n<li>Send request.</li>\n</ul>\n</li>\n<li>\n<p><strong>Model Response (Final):</strong></p>\n<ul>\n<li>Assume model confirms the refactoring is done.</li>\n<li>Stream event 1: <code>response.output_item.done</code> with <code>item: { type: &quot;message&quot;, role: &quot;assistant&quot;, content: [{ type: &quot;output_text&quot;, text: &quot;OK, I've refactored utils.ts to use arrow functions.&quot; }] }</code>.</li>\n<li>Stream event 2: <code>response.completed</code>, <code>id: &quot;resp_3&quot;</code>.</li>\n<li>Agent receives the message. <code>onLastResponseId</code> called with <code>&quot;resp_3&quot;</code>.</li>\n<li>No more tool calls. The loop finishes for this turn. UI stops showing &quot;Thinking...&quot;.</li>\n</ul>\n</li>\n<li>\n<p><strong>User Interaction:</strong></p>\n<ul>\n<li>The user sees the final message and the updated prompt, ready for the next command. The file <code>utils.ts</code> on their disk has been modified.</li>\n</ul>\n</li>\n</ol>\n",
  "content_markdown": "OpenAI Codex is a open source CLI released with OpenAI o3/o4-mini to be a \"chat-driven development\" tool. It allows developers to use AI models via API directly in their terminal to perform coding tasks. Unlike a simple chatbot, it can read files, write files (via patches), execute shell commands (often sandboxed), and iterate based on the results and user feedback.\n\n*Note: This overview was generated with Gemini 2.5 Pro and updated collaboratively iterated on with Gemini 2.5 Pro and myself.*\n\n## Core Components & Workflow\n\n### User Interface (UI)\n\n- The interactive terminal UI is built using `ink` and `react`, offering a richer experience than plain text. Key components reside in [`src/components/`](https://github.com/openai/codex/tree/main/codex-cli/src/components/), particularly within [`src/components/chat/`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/).\n- The application entry point is [`src/cli.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx) (using `meow` for argument parsing), which sets up the main [`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx) component via [`src/app.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx).\n- [`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx) manages the overall display including history, input prompts, loading states, and overlays.\n- User input is handled by [`TerminalChatInput`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-input.tsx) (or [`TerminalChatNewInput`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-new-input.tsx)), supporting command history and slash commands.\n- The conversation history is displayed by [`TerminalMessageHistory`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-message-history.tsx), using components like [`TerminalChatResponseItem`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-response-item.tsx) to render different message types.\n\n### Agent Loop\n\n- The core logic resides in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts).\n- The `AgentLoop` class manages the interaction cycle with the OpenAI API.\n- It takes the user's input, combines it with conversation history and instructions, and sends it to the model.\n- It uses the `openai` Node.js library (v4+) and specifically calls `openai.responses.create`, indicating use of the `/responses` endpoint which supports streaming and tool use.\n\n### Model Interaction\n\n- The `AgentLoop` sends the context (history, instructions, user input) to the specified model (default `o4-mini`, configurable via `--model` or config file).\n- It requests a *streaming* response.\n- It handles different response item types (`message`, `function_call`, `function_call_output`, `reasoning`).\n- [`src/utils/model-utils.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/model-utils.ts) handles fetching available models and checking compatibility.\n\n### Tools & Execution\n\n- The primary \"tool\" defined is `shell` (or `container.exec`), allowing the model to request shell command execution. See the `tools` array in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L512).\n\n#### Command Execution\n\n- When the model emits a `function_call` for `shell`, the `AgentLoop` invokes `handleExecCommand` ([`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)).\n- This function checks the approval policy (`suggest`, `auto-edit`, `full-auto`).\n- [`src/approvals.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts) (`canAutoApprove`) determines if the command is known-safe or needs user confirmation based on the policy.\n- If confirmation is needed, the UI ([`TerminalChatCommandReview`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx)) prompts the user.\n- If approved (or auto-approved), the command is executed via [`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts).\n\n#### Sandboxing\n\n- The execution logic in `handleExecCommand` decides *how* to run the command based on the approval policy and safety assessment.\n- `full-auto` mode implies sandboxing.\n- [`src/utils/agent/sandbox/`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/) contains the sandboxing implementations:\n  - [`macos-seatbelt.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/macos-seatbelt.ts): Uses macOS's `sandbox-exec` to restrict file system access and block network calls (`READ_ONLY_SEATBELT_POLICY`). Writable paths are whitelisted.\n  - [`raw-exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/sandbox/raw-exec.ts): Executes commands directly without sandboxing (used when sandboxing isn't needed or available).\n  - Linux: The [`README.md`](https://github.com/openai/codex/blob/main/codex-cli/README.md), [`Dockerfile`](https://github.com/openai/codex/blob/main/codex-cli/Dockerfile), and [`scripts/`](https://github.com/openai/codex/tree/main/codex-cli/scripts/) indicate a Docker-based approach. The CLI runs inside a minimal container where [`scripts/init_firewall.sh`](https://github.com/openai/codex/tree/main/codex-cli/scripts/init_firewall.sh) uses `iptables`/`ipset` to restrict network access only to the OpenAI API. The user's project directory is mounted into the container.\n\n#### File Patching (`apply_patch`)\n\n- The model is instructed (via the system prompt in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts)) to use a specific format like `{\"cmd\":[\"apply_patch\",\"*** Begin Patch...\"]}` when it wants to edit files.\n- `handleExecCommand` detects this pattern.\n- Instead of running `apply_patch` as a shell command, it uses `execApplyPatch` ([`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts)), which calls `process_patch` from [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts).\n- [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts) parses the patch format and uses Node.js `fs` calls to modify files directly on the host system (or within the container on Linux).\n- [`parse-apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/parse-apply-patch.ts) (likely used by the UI) helps render diffs for user review.\n\n### Prompts & Context Awareness\n\n- **System Prompt:** A long, detailed system prompt is hardcoded as `prefix` within [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/blob/b0ccca555685b1534a0028cb7bfdcad8fe2e477a/codex-cli/src/utils/agent/agent-loop.ts#L1021). This tells the model about its role as the Codex CLI, its capabilities (shell, patching), constraints (sandboxing), and coding guidelines.\n- **User Instructions:** Instructions are gathered from both global (`~/.codex/instructions.md`) and project-specific (`codex.md` or similar, discovered via logic in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)) files. These combined instructions are prepended to the conversation history sent to the model.\n- **Conversation History:** The `items` array (containing `ResponseItem` objects like user messages, assistant messages, tool calls, tool outputs) is passed back to the model on each turn, providing conversational context. [`src/utils/approximate-tokens-used.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/approximate-tokens-used.ts) estimates context window usage.\n- **File Context (Standard Mode):** The agent doesn't automatically read project files. It gains file context only when the model explicitly requests to read a file (e.g., via `cat`) or when file content appears in the output of a previous command (e.g., `git diff`).\n- **File Context (Experimental `--full-context` Mode):** This mode utilizes a distinct flow (see [`src/cli_singlepass.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli_singlepass.tsx), [`src/utils/singlepass/`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/)). It involves:\n  - Walking the directory, reading, and caching files via [`src/utils/singlepass/context_files.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context_files.ts).\n  - Formatting the prompt, directory structure, and file contents into a single large request using [`src/utils/singlepass/context.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/context.ts).\n  - Expecting the model to return all file changes (creations, updates, deletes, moves) in a specific Zod schema defined in [`src/utils/singlepass/file_ops.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/singlepass/file_ops.ts).\n- **Configuration:** Stores default model, approval mode settings, etc. Managed by [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts), loads from `~/.codex/config.yaml` (or `.yml`/`.json`) (not in repo).\n\n## Step-by-Step Manual Walkthrough (Simulating the CLI)\n\nLet's imagine the user runs: `codex \"Refactor utils.ts to use arrow functions\"` in a directory `/home/user/myproject`.\n\n1.  **Initialization ([`cli.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/cli.tsx), [`app.tsx`](https://github.com/openai/codex/tree/main/codex-cli/src/app.tsx)):**\n\n    - Parse arguments: Prompt is \"Refactor...\", model is default (`o4-mini`), approval mode is default (`suggest`).\n    - Load config (`loadConfig` in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)): Read `~/.codex/config.yaml` and `~/.codex/instructions.md`.\n    - Discover and load project docs (`loadProjectDoc` in [`src/utils/config.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/config.ts)): Find `/home/user/myproject/codex.md` and read its content.\n    - Combine instructions: Merge user instructions and project docs.\n    - Check Git status (`checkInGit` in [`src/utils/check-in-git.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/check-in-git.ts)): Confirm `/home/user/myproject` is a Git repo.\n    - Render the main UI ([`TerminalChat`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat.tsx)).\n2.  **First API Call (`AgentLoop.run` in [`src/utils/agent/agent-loop.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/agent-loop.ts)):**\n\n    - Create initial input: `[{ role: \"user\", content: [{ type: \"input_text\", text: \"Refactor...\" }] }]`.\n    - Construct API request payload: Include system prompt (from `prefix`), combined instructions, and the user input message. Set `model: \"o4-mini\"`, `stream: true`, `tools: [...]`. No `previous_response_id`.\n    - Send request: Call `openai.responses.create(...)` (using the `openai` library). UI shows \"Thinking...\".\n3.  **Model Response (Stream):**\n\n    - Assume the model decides it needs to read the file first.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"function_call\", name: \"shell\", arguments: '{\"cmd\": [\"cat\", \"utils.ts\"]}', call_id: \"call_1\" }`\n    - Stream event 2: `response.completed` with `output: [...]` containing the same function call, `id: \"resp_1\"`.\n    - Agent receives the function call. `onLastResponseId` is called with `\"resp_1\"`.\n4.  **Tool Call Handling (`handleExecCommand` in [`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)):**\n\n    - Parse arguments: `cmd = [\"cat\", \"utils.ts\"]`.\n    - Check approval: `canAutoApprove([\"cat\", \"utils.ts\"], \"suggest\", [\"/home/user/myproject\"])` (in [`src/approvals.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/approvals.ts)) -> returns `{ type: \"auto-approve\", reason: \"View file contents\", group: \"Reading files\", runInSandbox: false }`.\n    - Execute command (`execCommand` in [`src/utils/agent/handle-exec-command.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/handle-exec-command.ts)): Run `cat utils.ts` directly (no sandbox needed for safe commands). *Note: Assuming `utils.ts` exists at the root for this example; in reality, the model might need to specify a path like `src/utils.ts`.*\n    - Simulate result: `stdout = \"/* content of utils.ts */\", stderr = \"\", exitCode = 0`.\n5.  **Second API Call (`AgentLoop.run` continues):**\n\n    - Format tool result: Create a `function_call_output` item like `{ type: \"function_call_output\", call_id: \"call_1\", output: '{\"output\": \"/* content ... */\", \"metadata\": {\"exit_code\": 0, ...}}' }`.\n    - Construct API request payload: Include system prompt, combined instructions, the *entire history so far* (user message, assistant function call request, function call output), set `previous_response_id: \"resp_1\"`.\n    - Send request. UI shows \"Thinking...\".\n6.  **Model Response (Stream):**\n\n    - Assume model generates the refactored code and decides to apply it.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"function_call\", name: \"shell\", arguments: '{\"cmd\": [\"apply_patch\", \"*** Begin Patch\\n*** Update File: utils.ts\\n@@ ... -old +new ...\\n*** End Patch\"]}', call_id: \"call_2\" }`.\n    - Stream event 2: `response.completed` with `output: [...]` containing the patch function call, `id: \"resp_2\"`.\n    - Agent receives the patch function call. `onLastResponseId` is called with `\"resp_2\"`.\n7.  **Tool Call Handling (Patch):**\n\n    - Parse arguments: Identify `apply_patch` and extract the patch text.\n    - Check approval: `canAutoApprove([\"apply_patch\", \"...\"], \"suggest\", [\"/home/user/myproject\"])`. Since policy is `suggest`, this returns `{ type: \"ask-user\", applyPatch: { patch: \"...\" } }`.\n    - Request confirmation (`requestConfirmation`): The UI ([`TerminalChatCommandReview`](https://github.com/openai/codex/tree/main/codex-cli/src/components/chat/terminal-chat-command-review.tsx)) displays the patch diff and asks \"Allow command? \\[y/N/e/a\\]\".\n    - User reviews and presses 'y'. `submitConfirmation` is called with `{ decision: ReviewDecision.YES }`.\n    - Execute patch (`execApplyPatch` in [`src/utils/agent/exec.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/exec.ts) -> `process_patch` in [`src/utils/agent/apply-patch.ts`](https://github.com/openai/codex/tree/main/codex-cli/src/utils/agent/apply-patch.ts)): Reads `utils.ts`, applies the diff logic, and writes the modified content back using Node.js `fs.writeFileSync`.\n    - Simulate result: `stdout = \"Done!\", stderr = \"\", exitCode = 0`.\n8.  **Third API Call:**\n\n    - Format tool result: Create `function_call_output` item for the patch, `{ call_id: \"call_2\", output: '{\"output\": \"Done!\", ...}' }`.\n    - Construct API request: Include history + patch result, `previous_response_id: \"resp_2\"`.\n    - Send request.\n9.  **Model Response (Final):**\n\n    - Assume model confirms the refactoring is done.\n    - Stream event 1: `response.output_item.done` with `item: { type: \"message\", role: \"assistant\", content: [{ type: \"output_text\", text: \"OK, I've refactored utils.ts to use arrow functions.\" }] }`.\n    - Stream event 2: `response.completed`, `id: \"resp_3\"`.\n    - Agent receives the message. `onLastResponseId` called with `\"resp_3\"`.\n    - No more tool calls. The loop finishes for this turn. UI stops showing \"Thinking...\".\n10. **User Interaction:**\n\n    - The user sees the final message and the updated prompt, ready for the next command. The file `utils.ts` on their disk has been modified.\n",
  "dateCreated": "2026-09-27T19:29:15.293681927+00:00",
  "date_created": "2025-04-17T00:00:00+00:00",
  "date_modified": "2025-04-17T00:00:00+00:00",
  "date_published": "2025-04-17T00:00:00+00:00",
  "description": "I used Gemini 2.5 Pro to better understand the OpenAI Codex CLI, a tool that allows you to interact with an AI model directly in your terminal to perform coding tasks.",
  "external_url": "https://www.philschmid.de/openai-codex-cli",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/philschmid-de/2025/04/2025-04-17-openai-codex-cli-how-does-it-work.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/philschmid-de/2025/04/2025-04-17-openai-codex-cli-how-does-it-work.md"
  },
  "id": "urn:aggr:item:e78fa93e53175d473ad095ab07e0836f5b2a17aa",
  "isBasedOn": {
    "@id": "https://www.philschmid.de/openai-codex-cli"
  },
  "mainEntity": {
    "@id": "https://www.philschmid.de/openai-codex-cli",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/philschmid-de/2025-04-17-openai-codex-cli-how-does-it-work/#webpage"
    },
    "dateModified": "2025-04-17T00:00:00+00:00",
    "datePublished": "2025-04-17T00:00:00+00:00",
    "headline": "OpenAI Codex CLI, how does it work?",
    "timeRequired": "PT7M",
    "url": "https://www.philschmid.de/openai-codex-cli",
    "wordCount": 1503
  },
  "name": "Archived snapshot: OpenAI Codex CLI, how does it work?",
  "preview": null,
  "reading_minutes": 7,
  "replicated_at": null,
  "source": "philschmid-de",
  "source_name": "philschmid.de - RSS feed",
  "summary": "I used Gemini 2.5 Pro to better understand the OpenAI Codex CLI, a tool that allows you to interact with an AI model directly in your terminal to perform coding tasks.",
  "tags": [],
  "temporalCoverage": "2026-09-27T19:29:15.293681927+00:00",
  "title": "OpenAI Codex CLI, how does it work?",
  "url": "https://aggr.aymericbeaumet.com/items/philschmid-de/2025-04-17-openai-codex-cli-how-does-it-work/",
  "word_count": 1503
}