Skip to content

Instantly share code, notes, and snippets.

@AlexMeuer
Created June 14, 2026 18:53
Show Gist options
  • Select an option

  • Save AlexMeuer/03973e03d5a9e83a5bf55cdccd755ba8 to your computer and use it in GitHub Desktop.

Select an option

Save AlexMeuer/03973e03d5a9e83a5bf55cdccd755ba8 to your computer and use it in GitHub Desktop.
Claude Statusline
#!/usr/bin/env bash
# Claude Code statusline — Gruvbox Material Dark, minimal, single-line
# Segment order: Model · Context tokens · RateLimit? · Worktree? · Agent? · Caveman?
input=$(cat)
# ── Gruvbox Material Dark palette (256-color approximations via truecolor) ──
# Using \033[38;2;R;G;Bm for fg, \033[48;2;R;G;Bm for bg
fg() { printf '\033[38;2;%s;%s;%sm' "$1" "$2" "$3"; }
# bg() { printf '\033[48;2;%s;%s;%sm' "$1" "$2" "$3"; } # not needed for borderless style
reset='\033[0m'
bold='\033[1m'
# Colors (R G B)
c_fg="212 190 152" # #d4be98 fg
c_red="234 105 98" # #ea6962
c_green="169 182 101" # #a9b665
c_yellow="216 166 87" # #d8a657
c_blue="125 174 163" # #7daea3
c_purple="211 134 155" # #d3869b
c_aqua="137 180 130" # #89b482
c_orange="231 138 78" # #e78a4e
c_gray="146 131 116" # #928374
c_dim="50 48 47" # #32302f — near-background, for separators
SEP="" # U+2502 — box-drawing vertical bar
# Helper: emit a colored segment followed by a gray soft separator
# Usage: seg COLOR_ARGS text [include_sep=1]
emit() {
local color="$1" text="$2" sep="${3:-1}"
printf '%b%s%b' "$(fg $color)" "$text" "$reset"
if [ "$sep" = "1" ]; then
printf ' %b%s%b ' "$(fg $c_dim)" "$SEP" "$reset"
fi
}
# ── 1. Model ──────────────────────────────────────────────────────────────────
model=$(printf '%s' "$input" | jq -r '.model.display_name // empty')
# Shorten common model names
case "$model" in
"Claude Sonnet 4.6"|"claude-sonnet-4-6") model="Sonnet 4.6" ;;
"Claude Opus 4.8"|"claude-opus-4-8") model="Opus 4.8" ;;
"Claude Haiku"*) model="${model/Claude /}" ;;
"Claude "*) model="${model/Claude /}" ;;
esac
# ── 2. Context window bar + token count ──────────────────────────────────────
ctx_used=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')
ctx_tokens=$(printf '%s' "$input" | jq -r '.context_window.total_input_tokens // empty')
ctx_part=""
if [ -n "$ctx_used" ]; then
ctx_int=$(printf '%.0f' "$ctx_used")
# Color based on usage
if [ "$ctx_int" -ge 90 ]; then
ctx_color="$c_red"
elif [ "$ctx_int" -ge 70 ]; then
ctx_color="$c_yellow"
else
ctx_color="$c_green"
fi
# Circle progress bar: 10 chars wide (each = 10%)
bar=""
filled=$(( ctx_int / 10 ))
empty=$(( 10 - filled ))
for i in $(seq 1 $filled); do bar="${bar}"; done
for i in $(seq 1 $empty); do bar="${bar}"; done
# Format token count: show as e.g. "42k" or raw if < 1000
tok_label=""
if [ -n "$ctx_tokens" ]; then
if [ "$ctx_tokens" -ge 1000 ]; then
tok_label="$(( ctx_tokens / 1000 ))k"
else
tok_label="${ctx_tokens}"
fi
fi
ctx_part="${bar} ${tok_label}"
fi
# ── 3. Rate limit (5h only, when present) ────────────────────────────────────
rl_part=""
rl_pct=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
rl_reset=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
if [ -n "$rl_pct" ]; then
rl_int=$(printf '%.0f' "$rl_pct")
rl_countdown=""
if [ -n "$rl_reset" ]; then
now=$(date +%s)
rl_secs=$(( rl_reset - now ))
if [ "$rl_secs" -gt 0 ]; then
rl_h=$(( rl_secs / 3600 ))
rl_m=$(( (rl_secs % 3600) / 60 ))
if [ "$rl_h" -gt 0 ]; then
rl_countdown=" ${rl_h}h ${rl_m}m"
else
rl_countdown=" ${rl_m}m"
fi
fi
fi
rl_bar=""
rl_filled=$(( rl_int / 10 ))
rl_empty=$(( 10 - rl_filled ))
for i in $(seq 1 $rl_filled); do rl_bar="${rl_bar}"; done
for i in $(seq 1 $rl_empty); do rl_bar="${rl_bar}"; done
rl_part="${rl_bar}${rl_countdown}"
fi
# ── 7. Worktree (only when in a --worktree session) ───────────────────────────
wt_name=$(printf '%s' "$input" | jq -r '.worktree.name // empty')
# ── 8. Agent (only when present) ──────────────────────────────────────────────
agent_name=$(printf '%s' "$input" | jq -r '.agent.name // empty')
# ── 9. Caveman badge ──────────────────────────────────────────────────────────
caveman_part=""
caveman_flag="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.caveman-active"
if [ -f "$caveman_flag" ] && [ ! -L "$caveman_flag" ]; then
cmode=$(head -c 64 "$caveman_flag" 2>/dev/null | tr -d '\n\r' | tr '[:upper:]' '[:lower:]')
cmode=$(printf '%s' "$cmode" | tr -cd 'a-z0-9-')
case "$cmode" in
off|lite|full|ultra|wenyan-lite|wenyan|wenyan-full|wenyan-ultra|commit|review|compress)
if [ -z "$cmode" ] || [ "$cmode" = "full" ]; then
caveman_part="CAVEMAN"
else
caveman_part="CAVEMAN:$(printf '%s' "$cmode" | tr '[:lower:]' '[:upper:]')"
fi
;;
esac
fi
# ── Assemble ──────────────────────────────────────────────────────────────────
out=""
append_seg() {
local text="$1" color="$2"
if [ -n "$text" ]; then
if [ -n "$out" ]; then
out="${out} $(printf '%b%s%b' "$(fg $c_dim)" "$SEP" "$reset") "
fi
out="${out}$(printf '%b%s%b' "$(fg $color)" "$text" "$reset")"
fi
}
# Model — blue
[ -n "$model" ] && append_seg "$model" "$c_blue"
# Context — color-coded (already computed ctx_color)
if [ -n "$ctx_part" ]; then
if [ -n "$out" ]; then
out="${out} $(printf '%b%s%b' "$(fg $c_dim)" "$SEP" "$reset") "
fi
out="${out}$(printf '%b%s%b' "$(fg $ctx_color)" "$ctx_part" "$reset")"
fi
# Rate limit — red/yellow based on pct
if [ -n "$rl_part" ]; then
if [ "$rl_int" -ge 80 ]; then
rl_color="$c_red"
else
rl_color="$c_yellow"
fi
append_seg "$rl_part" "$rl_color"
fi
# Worktree — purple (only when present)
[ -n "$wt_name" ] && append_seg "$wt_name" "$c_purple"
# Agent — green (only when present)
[ -n "$agent_name" ] && append_seg "$agent_name" "$c_green"
# Caveman badge — bold orange (only when active)
if [ -n "$caveman_part" ]; then
if [ -n "$out" ]; then
out="${out} $(printf '%b%s%b' "$(fg $c_dim)" "$SEP" "$reset") "
fi
out="${out}$(printf '%b%b%s%b' "$bold" "$(fg $c_orange)" "$caveman_part" "$reset")"
fi
printf '%s' "$out"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment