oh my posh

How Oh My Posh renders a zsh prompt and a Claude Code status line, and how Codex renders its native TUI status line.

Oh My Posh

Oh My Posh is a cross-platform prompt engine. A single theme describes blocks, segments, colors, icons, and templates; the engine combines that configuration with runtime data and prints the final ANSI-formatted line.

That rendering model works in several terminal interfaces, but the integration point is different in each one:

InterfaceWho invokes the rendererData sourceRenderer
zsh promptzsh hooks installed by oh-my-posh init zshshell, path, git, command status, and environmentOh My Posh
Claude Code status lineClaude Code runs the configured commandsession JSON on stdinOh My Posh
Codex status lineCodex TUICodex session stateCodex itself

The distinction matters: Oh My Posh directly renders the first two. Codex currently owns its footer and does not expose an external status-line command.

Render the zsh prompt

Install Oh My Posh and a Nerd Font, then add the initialization command to the end of ~/.zshrc:

eval "$(oh-my-posh init zsh --config ~/.config/ohmyposh/main.omp.json)"

Reload zsh:

exec zsh

oh-my-posh init zsh generates the zsh integration script. The script installs prompt hooks that collect the current directory, exit code, execution time, and other shell state. On every prompt, Oh My Posh evaluates the configured segments and returns the escape sequences assigned to zsh’s prompt.

A small theme with a left prompt and a right-aligned status area looks like this:

{
  "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
  "version": 3,
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "path",
          "style": "powerline",
          "foreground": "#ffffff",
          "background": "#0077c2",
          "powerline_symbol": "",
          "template": "  {{ .Path }} "
        },
        {
          "type": "git",
          "style": "powerline",
          "foreground": "#111111",
          "background": "#ffeb3b",
          "powerline_symbol": "",
          "template": "  {{ .HEAD }}{{ if .Working.Changed }} {{ end }} "
        }
      ]
    },
    {
      "type": "rprompt",
      "alignment": "right",
      "segments": [
        {
          "type": "executiontime",
          "style": "plain",
          "foreground": "#a0a0a0",
          "template": " {{ .FormattedMs }} "
        },
        {
          "type": "status",
          "style": "plain",
          "foreground": "#ff5f5f",
          "template": " exit {{ .Code }} "
        }
      ]
    }
  ]
}

Here, prompt renders on the left and rprompt renders against the right edge. The path and git segments inspect the current repository, while executiontime and status use information captured from the previous command. Conditional templates keep irrelevant segments hidden.

Render the Claude Code status line

Claude Code has an external status-line protocol. After each update, it runs a configured command, writes session data as JSON to the command’s stdin, and displays stdout at the bottom of the TUI.

Oh My Posh implements that protocol with oh-my-posh claude. Add it to ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "oh-my-posh claude",
    "padding": 0
  }
}

The data flow is:

Claude Code session JSON
        │ stdin
oh-my-posh claude
        │ POSH_CLAUDE_STATUS
Claude segment + theme templates
        │ stdout
Claude Code status line

Without --config, Oh My Posh uses its built-in Claude theme. To control the layout, point the command at a dedicated theme:

{
  "statusLine": {
    "type": "command",
    "command": "oh-my-posh claude --config ~/.config/ohmyposh/claude.omp.json",
    "padding": 0
  }
}

The theme needs a claude segment. It can also reuse general segments such as path and git:

{
  "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
  "version": 3,
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "claude",
          "style": "diamond",
          "leading_diamond": "",
          "trailing_diamond": "",
          "foreground": "#ffffff",
          "background": "#d97757",
          "template": " 󰯉 {{ .Model.DisplayName }}  ctx {{ .TokenGauge }}  {{ .FormattedCost }} "
        }
      ]
    }
  ]
}

The Claude segment parses model, token, cost, duration, workspace, rate-limit, vim-mode, agent, and pull-request fields from the session payload. Common template properties include:

PropertyValue
.Model.DisplayNameHuman-readable model name
.TokenGauge / .TokenUsagePercentContext-window gauge / percentage
.FormattedTokens / .FormattedCostHuman-readable token count / session cost
.FormattedDurationSession duration
.Workspace.CurrentDir / .Workspace.ProjectDirCurrent / project directory
.FiveHourGauge / .SevenDayGaugeAvailable rate-limit gauges
.Vim.Mode / .Agent.NameOptional vim mode / active agent

Some nested objects are absent when Claude Code does not provide the corresponding data. Guard optional values before dereferencing them:

{{ if .Agent }}agent {{ .Agent.Name }}{{ end }}

Configure the Codex status line

Codex has a status line at the bottom of its terminal UI, but its integration model differs from Claude Code. Codex does not currently pipe session JSON to an external renderer, and Oh My Posh does not provide an oh-my-posh codex command. The Codex footer is therefore configured and rendered natively.

The easiest way to change it is to run this slash command inside Codex:

/statusline

The picker lets you select and reorder fields, then persists the result to ~/.codex/config.toml. The equivalent direct configuration is:

[tui]
status_line = [
  "current-dir",
  "model-with-reasoning",
  "context-remaining",
  "used-tokens",
  "git-branch",
  "five-hour-limit",
  "weekly-limit",
  "fast-mode"
]

Order in the array is order in the footer. A shorter configuration is often easier to scan:

[tui]
status_line = ["model-with-reasoning", "context-remaining", "git-branch"]

Use an empty array to hide the Codex footer:

[tui]
status_line = []

Oh My Posh still renders the surrounding zsh prompt before and after the Codex process runs; it simply does not own the footer inside the Codex TUI. If Codex adds an external status-line protocol in the future, the Claude integration is the likely model: Codex would provide structured session data and invoke a dedicated Oh My Posh renderer.

Resources

https://ohmyposh.dev/docs/installation/prompt?shell=zsh

https://ohmyposh.dev/docs/configuration/block

https://ohmyposh.dev/docs/segments/cli/claude

https://code.claude.com/docs/en/statusline

https://developers.openai.com/codex/cli/slash-commands#configure-footer-items-with-statusline

https://developers.openai.com/codex/config-reference#configtoml

Designed by Canux