Skip to content

Instantly share code, notes, and snippets.

@alexreardon
Created August 11, 2026 01:25
Show Gist options
  • Select an option

  • Save alexreardon/0540d2a8e3cc96a72b93a8e0e0ef6cf3 to your computer and use it in GitHub Desktop.

Select an option

Save alexreardon/0540d2a8e3cc96a72b93a8e0e0ef6cf3 to your computer and use it in GitHub Desktop.
Claude Code status line: directory, git branch, model, and a coloured context-usage bar

Claude Code status line with a context usage bar

Shows the working directory, git branch, model, and how much of the model's context window is used, as a coloured bar.

page-destroyer main | Opus 5 | ████████░░░░ 63% 630k/1M
  • Green under 50 percent, yellow from 50, red from 80.
  • The bar is 12 cells. Change BAR_CELLS to make it wider or narrower.
  • The model name drops any trailing parenthetical, so Opus 5 (1M context) reads as Opus 5. The window size is already in the token counts.
  • The context segment is omitted when the harness sends no context data.

Install

Save the script and point statusLine at it.

curl -o ~/.claude/statusline-command.sh \
  https://gist.githubusercontent.com/alexreardon/0540d2a8e3cc96a72b93a8e0e0ef6cf3/raw/statusline-command.sh
chmod +x ~/.claude/statusline-command.sh

Then add this to ~/.claude/settings.json:

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

Requirements

bash, jq, awk, sed, git. All are present on macOS except jq (brew install jq).

Test it without Claude Code

The script reads one JSON object on stdin, so you can drive it by hand:

echo '{
  "model": { "display_name": "Opus 5 (1M context)" },
  "workspace": { "current_dir": "'"$PWD"'" },
  "context_window": {
    "used_percentage": 63,
    "total_input_tokens": 630000,
    "context_window_size": 1000000
  }
}' | bash ~/.claude/statusline-command.sh
#!/bin/bash
# Claude Code status line.
# Shows model, directory, git branch, and context window usage.
input=$(cat)
# The trailing parenthetical is dropped, e.g. "Opus 5 (1M context)" -> "Opus 5".
# The window size is already shown by the context bar.
model=$(echo "$input" | jq -r '.model.display_name' | sed -E 's/ *\([^()]*\) *$//')
dir=$(echo "$input" | jq -r '.workspace.current_dir')
dir_name=$(basename "$dir")
# Git branch, skipping optional locks so this never blocks on a concurrent git process.
branch=""
if git -C "$dir" --no-optional-locks rev-parse --is-inside-work-tree &>/dev/null; then
branch=$(git -C "$dir" --no-optional-locks branch --show-current 2>/dev/null)
fi
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
input_tokens=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty')
window_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty')
# ANSI colours, dimmed to suit both light and dark terminal themes.
BLUE=$'\033[2;34m'
RED=$'\033[2;31m'
MAGENTA=$'\033[2;35m'
YELLOW=$'\033[2;33m'
GREEN=$'\033[2;32m'
GREY=$'\033[2;37m'
RESET=$'\033[0m'
# Shortens a token count for the status line, e.g. 633000 -> 633k, 1000000 -> 1M.
abbreviate_tokens() {
awk -v n="$1" 'BEGIN {
if (n >= 1000000) {
value = n / 1000000
if (value == int(value)) { printf "%dM", value } else { printf "%.1fM", value }
} else if (n >= 1000) {
printf "%dk", n / 1000
} else {
printf "%d", n
}
}'
}
BAR_CELLS=12
context_segment=""
if [ -n "$used_pct" ]; then
# Green is healthy, yellow is a warning, red is danger.
context_colour="$GREEN"
if awk "BEGIN {exit !($used_pct >= 80)}"; then
context_colour="$RED"
elif awk "BEGIN {exit !($used_pct >= 50)}"; then
context_colour="$YELLOW"
fi
# A filled cell count, clamped so a rounding overshoot cannot draw past the bar.
filled=$(awk -v pct="$used_pct" -v cells="$BAR_CELLS" 'BEGIN {
n = int(pct / 100 * cells + 0.5)
if (n < 0) { n = 0 }
if (n > cells) { n = cells }
printf "%d", n
}')
filled_bar=""
empty_bar=""
for ((cell = 0; cell < filled; cell++)); do
filled_bar+="█"
done
for ((cell = filled; cell < BAR_CELLS; cell++)); do
empty_bar+="░"
done
tokens_suffix=""
if [ -n "$input_tokens" ] && [ -n "$window_size" ]; then
tokens_suffix=" $(abbreviate_tokens "$input_tokens")/$(abbreviate_tokens "$window_size")"
fi
context_segment=$(printf "%s%s%s%s%s %s%.0f%%%s%s%s" \
"$context_colour" "$filled_bar" "$RESET" \
"$GREY" "$empty_bar" \
"$context_colour" "$used_pct" \
"$GREY" "$tokens_suffix" "$RESET")
fi
branch_segment=""
if [ -n "$branch" ]; then
branch_segment=$(printf "%s%s%s" "$RED" "$branch" "$RESET")
fi
printf "%s%s%s" "$BLUE" "$dir_name" "$RESET"
if [ -n "$branch_segment" ]; then
printf " %s" "$branch_segment"
fi
printf " %s|%s %s" "$MAGENTA" "$RESET" "$model"
if [ -n "$context_segment" ]; then
printf " %s|%s %s" "$MAGENTA" "$RESET" "$context_segment"
fi
printf "\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment