notes

codex manual

First published: Last updated: 5071 words · 2 lines of code

Overview

codex.el provides an Emacs interface to the OpenAI Codex CLI, allowing you to interact with the Codex agent directly from within Emacs. The package is modeled after claude-code.el and shares a similar architecture and design philosophy.

The package embeds the Codex CLI inside an Emacs terminal emulator buffer (either eat or vterm), giving you a full-featured TUI experience without leaving your editor. You can start, stop, and manage multiple Codex instances across different projects, send commands and code from any buffer, toggle the Codex window on and off, and access all of the CLI’s slash commands through a transient menu.

The main capabilities of codex.el can be grouped thematically:

  • Session management — start Codex in the current project, resume or fork previous sessions, run multiple named instances side by side, and kill instances individually or all at once.
  • Sending commands and context — send freeform commands, send commands annotated with file and line context, send the active region or entire buffer, send file paths and images, and ask Codex to fix errors at point.
  • TUI interaction — send return, escape, and numeric responses to the Codex TUI; queue follow-up prompts; edit previous messages; inject mid-turn instructions; open the header search overlay; and display prompt autosuggestions with a distinct face.
  • Window and buffer management — toggle the Codex window, switch between instances, select from all running instances, and toggle read-only mode.
  • Hooks and notifications — auto-configure the Codex CLI hooks system so that Emacs receives lifecycle events (session start, tool use, permission requests, stop); trigger desktop notifications when Codex finishes and awaits input.
  • Transient menus — a main command menu and a slash commands menu, both accessible from the keyboard.
  • Model and configuration — change the model, reasoning effort, sandbox mode, approval policy, and profile on the fly through transient infixes.

The package requires Emacs 28.1 or later, transient 0.9.3 or later, inheritenv, and eat. The default terminal backend is eat. You can alternatively use vterm by installing it separately and setting codex-terminal-backend to vterm.

The development repository is on GitHub.

User options

Core settings

The user option codex-program specifies the path to the Codex binary. The default value is "codex", which relies on the binary being in your PATH. Change this if you have installed Codex to a non-standard location.

The user option codex-program-switches is a list of extra CLI flags to pass to Codex on every invocation. The default value is nil. Use this for flags that you always want applied but that are not covered by the dedicated user options below.

The user option codex-terminal-backend selects which terminal emulator to use for the Codex REPL. The choices are eat (the default) and vterm. The eat backend is recommended as it integrates more cleanly with Emacs and does not require compiling a dynamic module.

The user option codex-use-alt-screen controls whether Codex runs in its default alternate-screen TUI mode. The default is nil, so codex.el starts Codex with --no-alt-screen for inline scrollback mode. This avoids recurring stale-screen failures seen when Codex’s alternate-screen TUI and Emacs terminal buffers lose synchronization after interrupts, prompt editing, or heavy redraws. Set it to non-nil only if you explicitly want Codex’s alt-screen TUI.

The user option codex-disable-terminal-resize-reflow controls whether codex.el passes --disable terminal_resize_reflow to new Codex sessions. The default is t because Codex’s experimental terminal reflow rebuilds scrollback after width changes, while Emacs terminal buffers use the buffer itself as retained session history. Disable this option only if you prefer Codex’s own terminal reflow behavior.

The user option codex-term-name overrides the terminal type reported to Codex. The default is nil, meaning codex.el chooses a backend-appropriate TERM value. For eat, Codex buffers use Eat’s bundled eat-* terminfo even if the global eat-term-name has been customized; for vterm, Codex buffers keep vterm’s own default. Set this to a string such as "xterm-256color" only when your terminal environment requires a specific TERM value. The value is applied when the terminal subprocess starts, so changes affect new Codex buffers rather than already-running sessions.

In eat buffers, codex.el disables Eat shell integration for the Codex subprocess and ignores Eat’s private UI-command channel in the outer terminal, including in existing Codex buffers after codex.el is reloaded. Codex is itself a TUI that captures and re-renders tool output; if nested shell commands emit Eat-private OSC sequences, those sequences can leak into captured tool output and corrupt the outer terminal display.

In eat Codex buffers, codex.el also coalesces terminal output chunks that end in the middle of a CSI escape sequence. This protects Codex sessions from a known failure mode where the CLI emits a cursor-shape sequence such as ESC [ 0 SPC q across two process-output chunks and Eat tries to parse the incomplete first half as a complete sequence. Codex additionally strips aborted CSI fragments — a CSI sequence terminated by ESC instead of a final byte — because Eat misroutes the abort byte as part of the CSI function, desynchronising its cursor tracking and tripping an assertion in eat--t-cur-left on the next cursor move. If Eat still rejects an output chunk, codex.el logs the parser error, retries that chunk as plain readable text with terminal controls removed, and then keeps processing later queued output instead of letting one malformed chunk abort the whole burst.

The user option codex-startup-delay is a number of seconds to wait after starting the Codex process before displaying the buffer. The default is 0.1. Increasing this value can help fix terminal layout issues that occur when the buffer is displayed before Codex has fully initialized.

The user option codex-confirm-kill controls whether codex-kill and codex-kill-all ask for confirmation before killing instances. The default is t. Set it to nil if you prefer to kill instances without a prompt.

The user option codex-newline-keybinding-style controls how the return key behaves in Codex buffers. The default, newline-on-shift-return, makes S-RET insert a line break and plain RET submit the prompt, mirroring the behavior of claude-code.el. The other choices are newline-on-alt-return (M-RET for newline, RET to submit), shift-return-to-send (RET for newline, S-RET to submit), and super-return-to-send (RET for newline, s-RET — the COMMAND key on macOS — to submit). The line-break action is delivered to Codex as Ctrl+J (byte 0x0A), which the Codex CLI binds to its insert_newline editor action by default; submission is delivered as a plain Return.

In eat buffers, plain Return is dispatched as the same RET character event used by normal terminal input; Escape also goes through Eat’s key-event input path rather than raw string insertion. This keeps programmatic TUI actions aligned with real keypresses.

The user option codex-enable-prompt-autosuggestions controls whether codex.el styles prompt autosuggestions in eat buffers. The default is t. Codex renders placeholder and suggestion text after the terminal cursor; when that text arrives in Emacs without the CLI’s dim styling, codex.el recognizes known suggestions and applies codex-prompt-autosuggestion-face, which inherits shadow without forcing italic text. While an autosuggestion is visible, codex.el keeps point at the prompt cursor rather than the footer line that Codex renders below the prompt. The options codex-prompt-autosuggestion-placeholders, codex-prompt-autosuggestion-history-path, and codex-prompt-autosuggestion-history-limit control which built-in placeholder strings and recent history entries are recognized as autosuggestions. In eat Codex buffers, TAB first accepts the visible autosuggestion when there is one; otherwise it is sent through to the Codex TUI as a normal tab.

Sandbox and approval

The user option codex-sandbox-mode controls the sandboxing level for Codex. When nil (the default), the CLI’s own default is used. The other choices are read-only, workspace-write, and danger-full-access, which correspond to the CLI’s --sandbox flag values. This option is ignored when codex-full-auto is non-nil.

The user option codex-approval-policy sets the approval policy for tool use. When nil (the default), the CLI default applies. The choices are untrusted, on-request, and never, corresponding to the --ask-for-approval flag. This option is also ignored when codex-full-auto is non-nil.

The user option codex-full-auto enables fully autonomous mode by passing --dangerously-bypass-approvals-and-sandbox to Codex. The default is nil. When non-nil, this overrides both codex-sandbox-mode and codex-approval-policy. Use with caution.

Model and profile

The user option codex-model specifies a model override (e.g., "gpt-5.4"). The default is nil, which uses the CLI’s default model.

The user option codex-profile names a configuration profile. The default is nil, meaning the CLI default profile is used. Profiles allow you to maintain separate sets of configuration for different workflows.

The user option codex-reasoning-effort overrides the reasoning effort level. The default is nil. When set to a string value, it is passed via -c as the model_reasoning_effort configuration value.

Hooks integration

The user option codex-enable-hooks controls whether codex.el automatically configures the Codex CLI hooks system. The default is t. When enabled, activating codex-mode ensures that config.toml has codex_hooks = true under [features] and that hooks.json contains entries for all supported hook types.

The user option codex-hooks-config-path is the path to the Codex config.toml file. The default is "~/.codex/config.toml".

The user option codex-hooks-json-path is the path to the Codex hooks.json file. The default is "~/.codex/hooks.json".

The user option codex-emacsclient-program specifies the emacsclient executable used by the hook wrapper. The default is nil, meaning codex.el records the first emacsclient found in PATH when hooks are configured.

Background and contrast remapping

The Codex CLI has its own theme system, and the colors it emits do not always match the Emacs theme. Mismatches make terminal text unreadable in two directions: the CLI may paint light backgrounds on a dark Emacs theme (bright rectangles containing dark text), or dark backgrounds on a light Emacs theme (dark rectangles containing light text). A third kind of mismatch is low-contrast foreground colors that wash out against the effective background (e.g. bright cyan on a light default background, or dark red on a dark diff background). The remapping system runs after each batch of terminal output and addresses all three.

The user option codex-remap-light-backgrounds is the master switch. The default is t. When non-nil, background colors whose WCAG contrast against the Emacs default background exceeds codex-background-contrast-threshold are stripped (or replaced), and — when codex-minimum-contrast-ratio is also non-nil — low-contrast foregrounds are stripped as well.

The user option codex-card-background specifies the replacement color for clashing backgrounds. When nil (the default), clashing backgrounds are stripped entirely so the Emacs buffer background shows through. Set this to a color string (e.g. "#1a1b2e") to use a fixed replacement color instead.

The user option codex-background-contrast-threshold is a WCAG contrast ratio above which a CLI background is considered to clash with the Emacs theme. The default is 1.0, which strips any explicit background that is not identical to the Emacs default background — the cleanest result for users who want the Emacs theme to fully own the rendering. Codex’s diff foregrounds (colored + / - glyphs) still distinguish added and removed lines after the bg strip. Raise this to 3.0 (the WCAG AA threshold for large text) to preserve subtle low-contrast tints (e.g. light-green diff backgrounds on a light theme at contrast 1.04:1) and only strip clashing rectangles. Because the comparison is against the Emacs default background, the same threshold handles mismatches in either direction.

The user option codex-minimum-contrast-ratio is a WCAG contrast ratio below which the explicit foreground is stripped so the Emacs theme’s default foreground takes over. The default is 3.0. Set this to nil to disable contrast-based foreground remapping while keeping background remapping. Stripping the foreground rather than the background preserves the semantic tint of diff-added and diff-removed backgrounds while ensuring the text itself remains readable.

Because the remapping pass runs after every batch of terminal output, it only inspects the current eat display plus newly appended output since the previous pass, not the full retained scrollback. Perceived luminance results are also memoized in codex--color-luminance-cache — a process-wide hash table keyed by color string. The cache is small (one entry per distinct color) and is preserved across reloads of the package, so repeated contrast comparisons reduce to O(1) hash lookups instead of repeated color-name-to-rgb calls.

Why is this a post-hoc remap instead of a clean fix?

This feature exists because the Codex CLI emits 24-bit RGB escape codes for card backgrounds and some foregrounds. Those land as literal :foreground / :background text properties in the eat buffer, bypassing the Emacs face system entirely — there is no indirection point where the Emacs theme gets to participate.

The clean alternative would be to downgrade Codex to 256-color (which eat routes through eat-term-color-* faces that the Emacs theme already controls). That was attempted by setting COLORTERM= (empty) in the Codex subprocess environment. It did not work: Codex’s Rust UI code calls Color::Rgb(...) directly in several places (chat composer, diff blocks), bypassing its own stdout_color_level() detection. No env var or config key currently turns those call sites off, and NO_COLOR=1 is too aggressive (it disables all color).

This machinery should be revisited and deleted if Codex stops hardcoding Color::Rgb in its UI code, grows a config option to use the terminal palette, or starts honoring COLORTERM consistently. To verify: start a fresh Codex session and check whether the buffer contains literal #RRGGBB hex colors in its face text properties — if all colors route through eat-term-color-* faces, this whole section can go.

Notifications

The user option codex-enable-notifications controls whether notifications are shown when Codex finishes a task and is waiting for input. The default is t. Notifications are triggered by bell characters from the terminal or by Stop hook events.

The user option codex-notification-function specifies the function called for notifications. The function receives two arguments: a title string and a message string. The default is codex-default-notification, which displays a message in the echo area and pulses the mode line (Notification functions).

Window management

The user option codex-no-delete-other-windows prevents Codex windows from being deleted by delete-other-windows. The default is nil. Set this to t if you want the Codex window to persist when you use C-x 1 or similar commands.

The user option codex-toggle-auto-select controls whether codex-toggle automatically selects the Codex window after opening it. The default is nil, meaning the window is displayed but focus stays in the current window.

The user option codex-optimize-window-resize controls whether terminal reflows are suppressed when the window size has not changed. The default is t. This avoids redundant redraws while still keeping the terminal dimensions synchronized after width or height changes.

The user option codex-display-window-fn specifies the function used to display the Codex window. It must accept a buffer argument. The default is codex-display-buffer-same-window, which displays the Codex buffer in the current window. An alternative codex-display-buffer-below is also provided, which displays it below the currently selected window.

Images

The user option codex-default-images is a list of image file paths to attach at startup via the --image flag. The default is nil. Use this to always include certain screenshots or diagrams as context.

Emacs hooks

The hook codex-start-hook runs after a Codex instance starts. Use it to perform additional setup in the Codex buffer, such as enabling minor modes or customizing keybindings.

The abnormal hook codex-process-environment-functions lets you inject environment variables into the Codex process. Each function receives two arguments: the Codex buffer name and the project directory. Each function should return a list of strings in "VAR=VALUE" format.

The hook codex-event-hook runs when the Codex CLI triggers lifecycle events through the hooks system. This is an abnormal hook: functions are called with a single plist argument containing :type, :buffer-name, :json-data, and :args, and dispatch stops at the first non-nil return value. That value is returned to the Codex CLI hook process, which lets permission and tool hooks approve, deny, or block.

The user option codex-transcript-catch-up-on-stop controls whether Stop hooks repair stale terminal output from Codex JSONL transcripts. The default is nil because automatic repair can be visually disruptive in active terminal buffers; reloading from an older build also resets the old implicit default to nil unless you customized the option explicitly. When enabled, codex.el tracks the session id from hook JSON, finds the transcript under codex-transcript-sessions-directory, and appends the final agent message if the terminal buffer does not already contain it. Prefer calling codex-refresh-from-transcript explicitly when repairing a known stale buffer.

Eat terminal settings

The user option codex-eat-read-only-mode-cursor-type specifies the cursor appearance when the eat terminal is in read-only mode. The value is a list of the form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF). The default is (box nil nil), which shows a non-blinking filled box cursor.

The user option codex-eat-disable-cursor-blink controls whether Codex eat buffers map blinking terminal cursor states to non-blinking equivalents. The default is t. This keeps the terminal cursor visible while avoiding Eat’s graphical cursor blink timer, which redraws the whole frame and can flicker on macOS. Set this to nil if you want Codex to honor blinking cursor states exactly as emitted by the CLI.

The user option codex-eat-scrollback-size controls how much scrollback eat keeps for Codex buffers. The default is nil, meaning unlimited scrollback. This avoids losing earlier Codex output in long sessions; set it to a number of characters if you want a bounded buffer.

The user option codex-eat-preserve-scrollback controls whether Codex eat buffers strip CSI scrollback erase commands before Eat processes output. The default is t. Codex runs with --no-alt-screen by default so the Emacs buffer can serve as session history, but TUI redraws can still emit scrollback erase sequences that make Eat delete retained buffer text. Ordinary erase-below redraw commands still pass through so prompt menus and status areas can clear stale text.

The package also defines faces for the eat terminal that inherit from the corresponding eat faces: codex-eat-prompt-annotation-running-face, codex-eat-prompt-annotation-success-face, codex-eat-prompt-annotation-failure-face, codex-eat-term-bold-face, codex-eat-term-faint-face, codex-eat-term-italic-face, codex-eat-term-slow-blink-face, codex-eat-term-fast-blink-face, and font faces codex-eat-term-font-0-face through codex-eat-term-font-9-face. Customize these faces if you want the Codex terminal to look different from other eat buffers.

Vterm terminal settings

The user option codex-vterm-buffer-multiline-output controls whether multi-line terminal output is buffered to prevent flickering. The default is t. When enabled, rapid successive output chunks containing cursor movement sequences are accumulated and flushed as a single update.

The user option codex-vterm-multiline-delay sets the delay (in seconds) before processing buffered vterm output. The default is 0.01. Increase this if you still see flickering with the buffering enabled.

The user option codex-vterm-max-scrollback controls how many scrollback lines vterm keeps for Codex buffers. The default is 100000, which is vterm’s built-in maximum unless its native module is recompiled with a larger limit.

Commands

Session management

The command codex starts a Codex instance in the current project root or, if not in a project, in the directory of the current file. If a Codex instance is already running for that directory, you are prompted for an instance name so that multiple instances can coexist. With a single prefix argument (C-u), the cursor switches to the Codex buffer after starting. With a double prefix argument (C-u C-u), you are prompted for the project directory.

The command codex-start-in-directory always prompts for a directory before starting Codex, regardless of the current project. With a prefix argument, it also switches to the Codex buffer.

The command codex-resume resumes a previous Codex session by running codex resume. If other instances already exist for the directory, you are prompted for an instance name; otherwise the name defaults to "default". With a prefix argument, it passes --last to resume the most recent session.

The command codex-fork forks a previous session by running codex fork. Like codex-resume, it only prompts for an instance name when other instances exist, and accepts a prefix argument for --last.

The command codex-new-instance creates a new Codex instance and always prompts for an instance name, even if no other instances are running. This is useful when you want to name your instance from the start. It accepts the same prefix argument conventions as codex.

The command codex-kill kills the Codex instance associated with the current directory. If multiple instances are running for the directory, you are prompted to select one. If codex-confirm-kill is non-nil (the default), confirmation is required.

The command codex-kill-all kills all Codex instances across all directories. It reports the number of instances killed and, like codex-kill, respects the codex-confirm-kill setting.

Sending commands and context

The command codex-send-command reads a command from the minibuffer and sends it to the Codex instance for the current project. Input history is maintained in codex-command-history. With a prefix argument, the cursor switches to the Codex buffer after sending.

Programmatic callers that already know the target session can use the same terminal ordering through codex--send-command-to-buffer. It types the command into that specific Codex buffer, selects the buffer’s window, then submits it by calling codex--terminal-send-return interactively. Dollar commands trigger Codex’s skill completion UI, so they receive the additional Return events needed to accept the skill completion and submit the resulting prompt.

The command codex-send-command-with-context works like codex-send-command but appends a file reference (in @file:line format) to the command. If a region is active, it includes the line range of the region. This is particularly useful when you want to direct Codex’s attention to a specific location in your code.

The command codex-send-region sends the active region to Codex, or the entire buffer if no region is active. With a single prefix argument, it prompts for instructions to prepend to the text. With a double prefix argument, it also switches to the Codex buffer.

The command codex-send-buffer-file sends the file path of the current buffer to Codex, prefixed with @. This tells Codex to read the file. With a prefix argument, it prompts for instructions to include alongside the file reference. With a double prefix argument, it also switches to the Codex buffer.

The command codex-send-image prompts for an image file and sends its path to Codex prefixed with @. Use this to attach screenshots or diagrams as context for your request.

The command codex-fix-error-at-point examines the error at point (using Flycheck or help-at-pt), formats it with the file and line reference, and sends it to Codex with instructions to fix the error. With a prefix argument, it switches to the Codex buffer.

TUI key sequences

These commands send specific key sequences to the Codex TUI, allowing you to interact with Codex without switching to the terminal buffer.

The command codex-send-return sends a return key press. This is equivalent to pressing Enter in the Codex TUI and is often used to confirm actions.

The command codex-send-escape sends an escape key press, typically used to cancel or dismiss prompts. In eat buffers, C-g is also bound to this command.

The commands codex-previous-agent and codex-next-agent send Codex’s agent-navigation key sequences. In terminal buffers, M-<left> and M-<right> are bound to these commands so multi-agent sessions can switch between the main thread and subagent threads when Codex accepts agent navigation.

The command codex-edit-previous-message sends Esc Esc to walk back and edit the previous message. After sending the sequence, it switches to the Codex buffer so you can edit inline.

The command codex-queue-followup sends a Tab key press to queue a follow-up prompt while Codex is still working.

The command codex-inject-mid-turn sends a Return key press to inject instructions while Codex is in the middle of processing.

The command codex-header-search sends Ctrl+K to open the header search overlay in the Codex TUI.

The command codex-accept-prompt-autosuggestion accepts the visible prompt autosuggestion in an eat Codex buffer by sending only the suggested suffix to the terminal. It returns non-nil when it accepted a suggestion, which lets TAB handlers use it before falling back to a raw tab for Codex’s own queue/submit behavior.

The commands codex-send-1, codex-send-2, and codex-send-3 send the corresponding digit to the Codex TUI. These are useful for selecting numbered options in menus.

Buffer and window management

The command codex-toggle shows or hides the Codex window. If the Codex buffer is currently visible and another window exists, it deletes the Codex window; if the Codex window is the only window, it buries the buffer instead. If the buffer is hidden, it displays it using codex-display-window-fn. The codex-no-delete-other-windows parameter is applied to the window. If codex-toggle-auto-select is non-nil, focus moves to the Codex window when it is shown (Window management).

The command codex-switch-to-buffer switches to the Codex buffer for the current project. If multiple instances are running, you are prompted to select one. With a prefix argument, it shows all Codex instances across all directories.

The command codex-select-buffer prompts you to select from all running Codex instances across all directories and switches to the selected one.

The command codex-toggle-read-only-mode toggles the terminal between read-only mode and interactive mode. In read-only mode (eat’s Emacs mode or vterm’s copy mode), you can navigate and copy text using normal Emacs keybindings. In interactive mode, keystrokes are sent to the terminal.

Model and permissions

The command codex-cycle-permissions sends /permissions to the Codex TUI to cycle through approval modes.

Diagnostics

When the Codex buffer displays rendering artifacts — such as colored rectangles with invisible text — these diagnostic commands help identify the root cause by inspecting the face properties that the terminal emulator has applied.

The command codex-diagnose-faces-at-point reports the face plist at point, including the explicit and effective foreground and background colors, the WCAG contrast ratio between them, the :inherit chain, and whether the background remapping system would process this span. Run this with point on a visually corrupted region to see whether the issue is a low-contrast color combination, a missing foreground, or a background that falls below the remapping threshold (Background color remapping).

The command codex-diagnose-faces-in-region audits all face property spans between BEG and END, reporting any non-whitespace text with a contrast ratio below 3:1. With no active region, it audits the visible portion of the buffer. The output lists the line number, contrast ratio, foreground, background, and a text excerpt for each problematic span.

The command codex-redraw asks the Codex TUI to repaint and then forces the Emacs terminal backend to redisplay. It is bound to C-l in Codex buffers and to l in codex-command-map. This is mainly a recovery command for existing or explicitly opted-in alt-screen sessions; new sessions avoid that failure class by default because codex-use-alt-screen is nil.

Functions

Notification functions

The function codex-default-notification is the default notification handler. It takes a title and message, displays them in the echo area, and pulses the mode line three times. You can replace this by setting codex-notification-function to a custom function, for example one that uses alert.el or the system notification center (Notifications).

The function codex-display-buffer-same-window displays the Codex buffer in the current window using display-buffer-same-window. It is the default value of codex-display-window-fn (Window management).

The function codex-display-buffer-below displays the Codex buffer below the currently selected window using display-buffer-below-selected.

Hook handling

The hook path has two stages. The codex-hook-wrapper shell script is the command recorded in hooks.json; it reads the hook JSON on standard input, writes that JSON to a private temporary file, and calls codex-handle-hook-from-emacsclient via emacsclient targeted at the Emacs server that configured the hooks. The wrapper retries transient emacsclient socket failures briefly; if dispatch still fails, gatekeeping hook types such as PreToolUse and PermissionRequest fail closed. The argv protocol after the hook type and buffer name is json-file JSON-FILE response-file RESPONSE-FILE ..., so large or sensitive hook JSON does not travel through argv and Emacs can write a hook response back to the wrapper. Hook installation also replaces older notify-emacs-hook.sh entries so stale wrappers cannot feed hook JSON back to Codex as terminal input.

The function codex-handle-hook-from-emacsclient parses that protocol from server-eval-args-left and delegates to codex-handle-hook. Direct Elisp callers can call codex-handle-hook with a hook type (e.g., "Stop", "PreToolUse"), a buffer name, hook JSON data, and optional additional arguments. It constructs a plist and runs codex-event-hook with it until the first handler returns non-nil. Hooks marked for notification, currently "Stop", also trigger a notification (Notifications).

Before user hook handlers run, codex-handle-hook also updates the target buffer’s transcript metadata. On Stop events it can call codex-refresh-from-transcript internally, so a stale terminal buffer still shows the final recorded agent message.

Transient menus

codex.el provides two transient menus for convenient access to its commands.

The transient codex-transient is the main command menu (titled “Codex Menu”), organized into five columns: Start/Stop Codex, Send Commands, Manage Codex, Quick Responses, and Model & Config. The Model & Config column contains transient infixes that let you change codex-model, codex-reasoning-effort, codex-sandbox-mode, codex-approval-policy, and codex-profile on the fly without modifying your configuration. These infixes use two-key sequences prefixed with g (e.g. g m for model, g e for reasoning effort, g s for sandbox mode, g a for approval policy, g p for profile).

The transient codex-slash-commands provides quick access to all Codex CLI slash commands, organized into five groups: Core (help, clear, compact, status, new, quit), Navigation & Review (diff, review, fork, resume, copy), Configuration (permissions, model, fast, plan, init, statusline, theme, debug config), Features & Tools (experimental, MCP, agent, apps, mention, ps), and Account & Identity (logout, personality, feedback).

Both transients are available from the codex-command-map keymap, bound to m and / respectively.

Keymap

The codex-command-map keymap provides quick access to all commands. You should bind this map to a prefix key of your choice, for example:

(global-set-key (kbd "C-c x") codex-command-map)

The default bindings are:

KeyCommand
ccodex
dcodex-start-in-directory
Rcodex-resume
fcodex-fork
icodex-new-instance
kcodex-kill
Kcodex-kill-all
scodex-send-command
xcodex-send-command-with-context
rcodex-send-region
ocodex-send-buffer-file
Icodex-send-image
ecodex-fix-error-at-point
/codex-slash-commands
tcodex-toggle
bcodex-switch-to-buffer
Bcodex-select-buffer
lcodex-redraw
zcodex-toggle-read-only-mode
Mcodex-cycle-permissions
ycodex-send-return
ncodex-send-escape
Ecodex-edit-previous-message
TABcodex-queue-followup
1codex-send-1
2codex-send-2
3codex-send-3
mcodex-transient

Minor mode

The global minor mode codex-mode enables the Codex integration. When activated, it auto-configures the Codex CLI hooks system by ensuring that config.toml and hooks.json are set up correctly (Hooks integration). The mode adds a Codex lighter to the mode line.

Activate it with:

(codex-mode 1)

Or add it to your init file to enable it on startup.

Hooks system

The Codex CLI supports a hooks mechanism that notifies external programs of lifecycle events. codex.el takes advantage of this by shipping a bin/codex-hook-wrapper shell script that calls emacsclient to relay events back to the Emacs server that enabled codex-mode.

When codex-enable-hooks is non-nil and codex-mode is activated, codex.el automatically:

  1. Ensures that config.toml has codex_hooks = true under the [features] section.
  2. Ensures that hooks.json has entries for all six supported hook types: Stop, SessionStart, PreToolUse, PermissionRequest, PostToolUse, and UserPromptSubmit.

Each hook entry points to the codex-hook-wrapper script, which reads JSON from stdin into a private temporary file and asks emacsclient to pass that file to codex-handle-hook. Existing user-defined hooks in hooks.json are preserved; codex.el appends its own entries if they are absent and repairs them if their matcher, command, type, or timeout drifts.

You can respond to these events by adding functions to codex-event-hook (Emacs hooks).

Indices

Function index

Variable index