Customizable status line
Feature Request
Problem
Claude Code has a built-in customizable status line feature that allows users to display useful real-time information at the bottom of the terminal UI — token usage, model name, rate limits, context window, git branch, etc.
This is configured via a simple shell script hook in settings:
{
"statusLine": {
"type": "command",
"command": "/bin/bash ~/.claude/statusline.sh",
"padding": 0
}
}
The script receives JSON context on stdin and returns formatted text. This is incredibly useful for power users who want to monitor their session at a glance.
Codex CLI currently has no equivalent mechanism. There's no way to display custom information in the TUI — no status line, no hooks, no plugin system for UI customization.
Proposed Solution
Add a statusLine (or similar) configuration option to ~/.codex/config.toml that allows running an external command and rendering its output in the Codex TUI (e.g., at the bottom of the screen).
Something like:
[status_line]
command = "/bin/bash ~/.codex/statusline.sh"
refresh_interval_secs = 10
The command would receive session context (model, token count, etc.) as JSON on stdin and return a single line of text (with ANSI colors) on stdout.
Use Cases
- Display current model and token/context usage
- Show API rate limit status and reset times
- Display git branch and repo info
- Show project-specific metadata
- Integration with external monitoring tools
Why This Matters
For users who switch between Claude Code and Codex, the lack of a status line in Codex is a noticeable gap. The status line is a low-cost, high-value feature that significantly improves the interactive experience.
29 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Have you tried the
/statuslinecommand? It's a little less flexible than an arbitrary script, but it's much easier to configure. Does this meet your needs?I'd like to be able to see my jj-vcs status (change id etc.) in the status line.
It's likely not a small task to invest in making jj a core part of the product, but allowing a hook like this seems like a reasonable compromise https://github.com/openai/codex/issues/16921 seems like they have a good solution to this with a proposed PR ready to review
The current exposed features have significantly enhanced the functionality, and they can meet the needs of most users in various scenarios. However, I still hope to be able to add an extension point similar to the Statusline of CC CLI. It can store some user-defined data. If it can be made available, I would be very grateful.
Found this while researching this exact idea.
/statusline is actually a decent compromise, though I would still like to have control over the wording and order for conciseness.
For example, I have my Claude one at
5H: 96% | 7D: 100% | context: 89% | Sonnet 4.6
Since I use a screen reader, being able to set the order is important to me.
The built-in
/statuslinecommand is useful, but it does not fully cover the use case of a dynamically refreshed status provider. The gap I am running into is less "show one more built-in field" and more "let the user define what the statusline and/or terminal title should say while a session is running."Useful shape:
This would make
/statuslinea good default for most users while still giving power users a narrow extension point for project-specific or workflow-specific context.Adding another +1 for command-driven customization specifically, not just selecting built-in
/statuslinefields.The current
/statuslineis useful, but the gap vs Claude Code is the extension point: let users run a command/script, pass Codex session context as JSON on stdin, and render stdout with safe timeout/failure behavior.Use cases:
A built-in
/statuslinedefault and an opt-in command provider could coexist: default remains simple, power users get a narrow, predictable extension hook.+1
Thanks, I noticed #17827 is very closely related.
I am fine with this issue being treated as a duplicate if that helps tracking. The main point I wanted to emphasize is the same as the later comments in #17827: the built-in
/statuslinepicker is useful, but the missing piece is a command-driven extension point.For my use case, the important part is not just adding more built-in fields. It is allowing a user-provided command to receive Codex session context as JSON on stdin and render stdout back into the TUI, preserving ANSI colors and custom formatting, with timeout/failure safeguards.
That would let the built-in
/statuslineremain the simple default while enabling advanced users and community tools to build richer status lines./statusline customize is ready. it's just i can't change the color of the statusline...
when will it get merged to main?
<img width="437" height="26" alt="Image" src="https://github.com/user-attachments/assets/70173c24-3343-40e7-9e75-d85a2295a6bc" />
I just finished customizing my statusline in another app and stumbled upon this request. This is reminiscent of the old days of internet quotas. I used to track with over/under indicators like I've done here.
Adding a similar scripting ability to Codex is a +1 from me.
Adding another concrete use case for command-backed status-line support:
I need to show local coordination/watch health in the Codex TUI footer, e.g.
watchers:livewatchers:stalewatchers:deadThe status comes from a local script that checks a daemon PID, output freshness, and pending inbox events. Today I can approximate this with
UserPromptSubmithooks that emitsystemMessage, but that is not equivalent: it only appears at turn boundaries and only as transient transcript output. The operator still has no persistent footer signal that the watcher is healthy while working.The current
[tui].status_line = [...]built-in picker is useful for Codex-owned state, but this is external workflow state. A command-backed status-line item or banner would solve it cleanly:Key requirements from this use case:
This would let Codex support project-local operational telemetry without expanding the built-in status enum for every workflow-specific field.
+1. I maintain token-tracker, which renders a rich quota / context / cost statusline on Claude Code via its official StatusLine API — but on Codex I'm stuck with the default style, since there's no custom hook. Same data locally, no way to render it.
!Claude Code statusline
Copying Claude Code's design would close the gap — a
commandthat gets session JSON on stdin and prints a styled string to stdout:Keep the enum items as default, treat
commandas opt-in. Happy to test a branch.+1 — this is the single biggest gap for me when switching between Claude Code and Codex.
A concrete reference that this is both feasible and high-value: I maintain
usage, a macOS menu-bar/TUI tool that pins Claude Code + Codex quota to the screen (all from local files — no API calls).On the Claude Code side it ships exactly the
statusLinecommand hook proposed here, and renders something like:…with unicode meters, per-threshold colors, and a derived "time-until-reset" — all from a single script that reads local files off stdin.
On the Codex side we're limited to the fixed
tui.status_lineenum, so the best we can offer users is plain text:Same underlying data, but we can't draw the meters / colors / countdowns because there's no command-backed hook to render arbitrary output.
The proposed
[status_line] command = "..."shape (JSON context on stdin → one ANSI line on stdout) is exactly right — it mirrors Claude Code 1:1, so existing scripts and tools port over with near-zero friction. If this lands, we'd ship Codex support for it the same week. 🙏I've prototyped a minimal version of this and would be glad to contribute it if the team is open to an invited PR (I see contributions are invitation-only — happy to follow whatever process you prefer).
Design — one self-contained
[tui]key, with no change to the existingstatus_lineitem list:The command is fed session context as JSON on stdin (
model,reasoning_effort,cwd,git_branch,session_id,approval_mode,sandbox_mode,context_used_pct/context_remaining_pct,context_window,codex_version) and its first stdout line is rendered as a status-line segment — mirroring Claude Code'sstatusLine.command. Execution is async / non-blocking: it reuses the existing hooks command-runner pattern (configurable timeout,kill_on_drop), re-runs on an interval, and the output is sanitized to a single escape-free line so it can't corrupt the TUI.It's implemented against
main, kept intentionally small (no/statuslinepicker changes), with config-deserialize + TUI render tests passing andcargo fmt/clippyclean.A couple of things I'd want the team's steer on before any PR:
Happy to share the branch or adjust the design to fit your roadmap. Thanks!
Command-backed status lines work if the contract is small and bounded. Send JSON with session id, model, cwd, git branch, approval/sandbox mode, context usage, quota snapshot, and version. Enforce timeout, refresh interval, max output width, and stale-output behavior. That lets local quota/watch tools render state without giving the command transcript access or blocking the TUI.
---
_Generated with ax._
For anyone who mainly wants local host telemetry in the meantime, I published a small tmux-based workaround: https://github.com/AlanineX/codex-host-status
It does not replace the native feature request here. It wraps interactive
codexsessions, leaves subcommands likecodex exec/codex doctoruntouched, and renders a compact status bar like:🐍 base ⚙ CPU 4% 41C 🎮 GPU 2% 43C 0.6G 💾 RAM 10.1/47G 🕒 14:29This covers my local CPU/GPU/RAM visibility use case while waiting for a real command-backed
tui.status_linehook in Codex.+1 on this. I shipped a workaround for the same use case as an open-source CLI (token-tracker) and want to share what users actually need vs. what the built-in
/statuslinecan express today.What we ended up doing: since Codex has no command-backed statusline hook, we inject a two-line "faux statusline" via the
Stophook, returningsystemMessageafter every turn. It renders with 24-bit truecolor, shows project + branch + diff + session tokens + cost + 5h/7d quota + context %, and follows the active theme. (Verified: does not enter the model context.)!Codex faux statusline screenshot
Why
/statuslinewasn't enough:What would unblock the whole class of tools: exactly what Claude Code does — accept a command/script-based statusline (stdin JSON in, formatted text out). Today we're stuck with a hidden Stop-hook workaround that renders in the response area (not the bottom bar), depends on Stop-hook + systemMessage being stable, and is hard for new users to discover.
Happy to share implementation details if useful. Thanks for considering.
+1. I run a workflow/governance tool that's meant to work across different agents, but it leans heavily on Claude Code's statusLine. We keep a little state file (active task, pipeline stage, drift, context left) that the hooks update, and the statusline just renders it. Codex already has the hooks now, there's just nowhere to show it natively. Would love to port it over: an opt-in { type = "command", command, timeout_ms } that gets the session JSON on stdin and renders stdout, with a timeout.
Thanks for the great work on this!
Related to this, here's a small tool. It is not a live status line, but it helps inspect local Codex/Claude session data so token usage and session details are less opaque, without API keys or sending logs anywhere.
Open source:
https://github.com/pzarzycki/token-companion
If you like it - leave a star; submit an issue or request, or even a PR!
Just want to add in that this would be extremely useful for improving the way the current statusline renders items when displaying multiple items. Codex cli is easiest to read when not set to the entire screen width, but then items overflow:
Being able to style these, and/or have some of them only appear at desired thresholds (like weekly/5h only appearing below a certain remaining level) enhances the statusline massively, it could instead render as
This is the same statusline information, but it now renders all the information (weekly is cut off originally).
Allowing the user to do this would be fantastic.
+1
We ship a tool that integrates with coding agents and the lack of a flexible status line is quite painful to our customers - it means they've got no way to display progress information from within our stack when the agent is driving our tool. It makes the workflow more opaque for them as they can't tell what the agent is doing or why.
Ideally we'd be able to supply a default script for status line behaviour that less advanced users can just configure, with more advanced users being able to script whatever they want from our feedback and other sources.
Edit to add: Alternatively, the ability to supply a JSON blob for formatting / filtering within the agent's status line config would also work well.
The current status line configuration is limited to built-in fields and does not support customer-specific workflow needs, such as command-backed content, semantic colors, or conditional indicators. Please consider supporting an extensible status line API.
I'd like to see this too.
Adding a concrete, shipping use case for a command-backed status line (distinct from picking more built-in fields).
We ship
$codex-usageas a Codex-native workflow. It reads rate-limit snapshots through the authenticatedcodex app-serverprotocol (it never opensauth.json) and renders a compact pace indicator against a 95%-utilization target. Its default output is already exactly one status line:i.e.
<project>(<branch>) <pace-glyph> <±pace-vs-target>% (<resets-in>), and it also emits a machine-readable payload a hook could consume directly:The one thing we can't do is surface this persistently in the TUI.
[tui].status_lineis a fixed enum of built-in item ids, so today the pace line only lives in an on-demand invocation or a transient session-start message — it can't stay pinned in the footer the way Claude Code'sstatusLine.commandkeeps a custom renderer live.The missing piece is exactly the extension point in this issue: Codex pipes session/rate-limit JSON to a user command on stdin and renders its stdout (first line, ANSI-aware) in the footer, with a timeout + fail-open so a slow or failing command never blocks the TUI. Additive to the existing field picker, roughly:
PR #10170 already demonstrated a working implementation; the status surface has since been refactored into
tui/src/bottom_pane/, so it would need a fresh pass on the current architecture rather than a straight rebase. Happy to help build and test it against a real renderer ($codex-usage) if there's maintainer appetite.I put together a working implementation on today's
bottom_panearchitecture: compare diff.It adds a
customstatus-line item backed by[tui].status_line_command(argv) — Codex runs it on a timer, pipes a small JSON session snapshot ({cwd, git_branch, model}) on stdin, and renders the first stdout line, with a 1.5s timeout + kill-on-drop and fail-open (keeps the last good value), mirroring the async workspace-headline item. A snapshot diff re-runs it immediately on a branch/dir switch so the footer isn't stuck on stale data. Rebases cleanly onmain;clippy/fmtclean; the command-runner unit tests plus the fullstatus_linetui suite pass.This repo limits opening PRs to collaborators, so I can't open one directly — happy to if a maintainer enables it, or the branch is here to cherry-pick:
shenxingy:feat/status-line-command.+1. Use case: side-by-side multi-terminal agent workflows (Claude Code + Codex CLI in split panes). We render cross-session mailbox/peer badges in Claude Code via its
statusLinecommand hook, but Codex's[tui].status_lineonly accepts built-in item identifiers — so the Codex pane can't show a symmetric indicator. A custom command item (or a single script-fed text item) would cover this.