How-To Guides

I Added a Custom Status Bar to Claude Code. Here’s How.

Somewhere around the third time I asked Claude to check something on the wrong branch, I decided to fix the problem properly. Two files and a bash script later, I have a live footer showing my git branch, open PR, and quota burn. Here's exactly how I built it.

  • One bash script surfaces live quota, context window, and PR number in Claude Code's persistent footer
  • Color-coded thresholds: green below 50%, yellow at 50-79%, red at 80%. No surprise cutoffs mid-session.
  • Git branch and open PR pulled automatically via gh CLI, so Claude always knows where it is working
  • ️ Zero new dependencies: uses python3, git, and gh. Tools you already have.
By Rejith Krishnan5 min read
I Added a Custom Status Bar to Claude Code. Here’s How.

Somewhere around the third time I caught myself asking Claude to check something on the wrong branch, I stopped and thought: there has to be a better way than squinting at the terminal title bar.

There is. Claude Code has a statusLine setting that lets you run any shell command and pin its output as a persistent footer, visible at the bottom of every session. Two files, a bash script, and about an hour of tinkering later, this is what sits at the bottom of my screen:

atithi · 10302/parsing_error_fix · #4258 · ctx 32% · 5h 18% · 7d 59%

Reading left to right: atithi is the project folder (shortened relative to ~/git). 10302/parsing_error_fix is the current git branch, shown in cyan. #4258 is the open GitHub PR for that branch, in yellow. Then the three percentages: context window fill, 5-hour session quota, and weekly quota. All three go green below 50%, yellow from 50 to 79%, and red at 80% and above.

It sounds like a small thing. It has quietly become one of those things I can't imagine working without.

What was actually breaking

I jump between four or five repos on a typical day and Claude Code doesn't display the current directory or branch anywhere obvious. The side effects crept up slowly.

The branch problem I already mentioned. The worse one was context blindness. I'd be an hour into a multi-file refactor, Claude's responses getting subtly vaguer, and I'd eventually realize the context window was at 87%. By then I'd already spent ten minutes wondering why the output felt off. The information existed. I just had no way to see it without interrupting the session to check.

The status bar fixes both. The branch is always visible. And the context percentage goes yellow well before things start degrading, so I can finish a thought, open a new session, and keep moving instead of getting blindsided mid-task.

The setup: two files

Claude Code passes a JSON payload on stdin to whatever command you point it at. No API calls, no polling, no background process. The command just reads stdin, formats a string, and exits.

~/.claude/settings.json

{
  "statusLine": {
    "type": "command",
    "command": "bash /home/youruser/.claude/statusline-command.sh"
  }
}

Swap /home/youruser for your actual home path.

~/.claude/statusline-command.sh

#!/usr/bin/env bash
input=$(cat)

# Parse the JSON Claude Code sends on stdin
eval "$(python3 -c "
import sys, json, shlex
try:
    d = json.loads(sys.stdin.read())
    cwd = d.get('cwd') or ''
    ctx = d.get('context_window', {}).get('used_percentage')
    five = (d.get('rate_limits') or {}).get('five_hour', {}).get('used_percentage')
    seven = (d.get('rate_limits') or {}).get('seven_day', {}).get('used_percentage')
    def fmt(v): return str(round(float(v))) if v is not None else ''
    print('cwd=' + shlex.quote(cwd))
    print('ctx_pct=' + shlex.quote(fmt(ctx)))
    print('five_pct=' + shlex.quote(fmt(five)))
    print('weekly_pct=' + shlex.quote(fmt(seven)))
except Exception:
    print(\"cwd='' ctx_pct='' five_pct='' weekly_pct=''\")
" <<< "$input")"

# Git branch
branch=$(git --git-dir="$cwd/.git" -C "$cwd" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-branch")

# Open PR for this branch (GIT_OPTIONAL_LOCKS=0 avoids index lock contention)
pr_num=$(cd "$cwd" 2>/dev/null && GIT_OPTIONAL_LOCKS=0 gh pr view --json number -q .number 2>/dev/null)

# Shorten the path relative to ~/git
folder="${cwd#$HOME/git/}"
[ "$folder" = "$cwd" ] && folder=$(basename "$cwd")

# Helper: color a percentage value with a label
color_pct() {
  local v=$1 label=$2
  [ -z "$v" ] && return
  if   [ "$v" -ge 80 ]; then c='\033[0;31m'
  elif [ "$v" -ge 50 ]; then c='\033[0;33m'
  else                        c='\033[0;32m'; fi
  printf "${c}${label} ${v}%%\033[0m"
}

folder_str=$(printf '\033[1;34m%s\033[0m' "$folder")
branch_str=$(printf '\033[1;36m%s\033[0m' "$branch")
[ -n "$pr_num" ] && pr_str=$(printf ' \033[1;33m#%s\033[0m' "$pr_num") || pr_str=""

ctx_str=$(color_pct "$ctx_pct" "ctx")
five_str=$(color_pct "$five_pct" "5h")
wk_str=$(color_pct "$weekly_pct" "7d")

out="${folder_str} · ${branch_str}${pr_str}"
[ -n "$ctx_str" ] && out="${out} · ${ctx_str}"
[ -n "$five_str" ] && out="${out} · ${five_str}"
[ -n "$wk_str"  ] && out="${out} · ${wk_str}"

printf '%s' "$out"

Make it executable, then restart Claude Code:

chmod +x ~/.claude/statusline-command.sh

That's it. The footer shows up immediately.

A few things worth knowing about the implementation

Why python3 instead of jq? jq isn't installed everywhere, especially on fresh VMs and Docker images. python3 is. The shlex.quote call handles the one real gotcha: paths with spaces would break the eval without it.

Why GIT_OPTIONAL_LOCKS=0? Without this flag, gh pr view tries to acquire Git's index lock, which Claude Code may already be holding during an active tool call. On large repos that caused the status line to flicker and occasionally hang for a second or two. The flag tells Git to skip optional locks for read operations, and the flickering stopped.

The JSON payload is richer than the docs imply. I'm only using four fields here (cwd, context_window.used_percentage, rate_limits.five_hour.used_percentage, rate_limits.seven_day.used_percentage), but there's more in there. Worth exploring if you want to surface something I haven't thought of.

What's still on my list

Three things I haven't gotten to yet:

  • The current model name (Opus vs. Sonnet), since the cost difference is real enough to be worth seeing at a glance
  • Some kind of active tool indicator for long-running operations, so the footer tells me Claude is still working rather than just showing percentages
  • A rough time-remaining estimate based on quota burn rate over the session

If you wire up something clever, I'd genuinely like to hear about it. Drop it in the comments.

About the Author

Rejith Krishnan

Rejith Krishnan

Founder and CEO

Rejith Krishnan is the Founder and CEO of lowtouch.ai, a platform dedicated to empowering enterprises with private, no-code AI agents. With expertise in Site Reliability Engineering (SRE), Kubernetes, and AI systems architecture, he is passionate about simplifying the adoption of AI-driven automation to transform business operations.

Rejith specializes in deploying Large Language Models (LLMs) and building intelligent agents that automate workflows, enhance customer experiences, and optimize IT processes, all while ensuring data privacy and security. His mission is to help businesses unlock the full potential of enterprise AI with seamless, scalable, and secure solutions that fit their unique needs.

LinkedIn →