# Powerline Status Line for Claude CLI

> Source: <https://gist.github.com/navidnabavi/edc399b1e36521a6e84e8f9d4f3c4c19>
> Published: 2026-05-30 22:26:20+00:00

| #!/bin/bash | |
| # Claude Code statusLine — sexy Powerlevel10k-style | |
| # Segments: session • cwd • git • vim • model • context bar • rate limits • caveman | |
| input=$(cat) | |
| # ── Palette ──────────────────────────────────────────────────────────────── | |
| RESET=$'\033[0m' | |
| BOLD=$'\033[1m' | |
| DIM=$'\033[2m' | |
| # Foreground | |
| FG_WHITE=$'\033[97m' | |
| FG_BLACK=$'\033[30m' | |
| FG_BLUE=$'\033[34m' | |
| FG_CYAN=$'\033[36m' | |
| FG_GREEN=$'\033[32m' | |
| FG_YELLOW=$'\033[33m' | |
| FG_RED=$'\033[31m' | |
| FG_MAGENTA=$'\033[35m' | |
| FG_ORANGE=$'\033[38;5;214m' | |
| FG_GRAY=$'\033[90m' | |
| # Background accents (used for mini-badge style) | |
| BG_BLUE=$'\033[44m' | |
| BG_CYAN=$'\033[46m' | |
| BG_GREEN=$'\033[42m' | |
| BG_YELLOW=$'\033[43m' | |
| BG_RED=$'\033[41m' | |
| BG_MAGENTA=$'\033[45m' | |
| BG_DARK=$'\033[48;5;236m' | |
| BG_ORANGE=$'\033[48;5;130m' | |
| # ── Helpers ──────────────────────────────────────────────────────────────── | |
| SEP="${FG_GRAY}│${RESET}" | |
| # Print a colored pill: bg fg text | |
| pill() { | |
| local bg="$1" fg="$2" text="$3" | |
| printf "${bg}${fg}${BOLD} %s ${RESET}" "$text" | |
| } | |
| # Print a dim label + colored value | |
| kv() { | |
| local label="$1" color="$2" value="$3" | |
| printf "${FG_GRAY}%s${RESET}${color}%s${RESET}" "$label" "$value" | |
| } | |
| # ── Parse JSON once ──────────────────────────────────────────────────────── | |
| cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // empty') | |
| model=$(echo "$input" | jq -r '.model.display_name // empty') | |
| session=$(echo "$input" | jq -r '.session_name // empty') | |
| remaining=$(echo "$input" | jq -r '.context_window.remaining_percentage // empty') | |
| vim_mode=$(echo "$input" | jq -r '.vim.mode // empty') | |
| five_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty') | |
| week_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty') | |
| # ── Segment: Session name ────────────────────────────────────────────────── | |
| if [ -n "$session" ]; then | |
| pill "$BG_DARK" "$FG_CYAN" "✦ $session" | |
| printf ' ' | |
| fi | |
| # ── Segment: Directory ──────────────────────────────────────────────────── | |
| if [ -n "$cwd" ]; then | |
| # Show last 2 path components for context | |
| dir_display=$(echo "$cwd" | awk -F'/' '{ | |
| n=NF | |
| if (n>=2) printf "%s/%s", $(n-1), $n | |
| else print $n | |
| }') | |
| # Replace $HOME with ~ | |
| dir_display=$(echo "$dir_display" | sed "s|^$HOME|~|") | |
| pill $'\033[48;5;24m' "$FG_WHITE" " $dir_display" | |
| fi | |
| # ── Segment: Git ────────────────────────────────────────────────────────── | |
| if [ -n "$cwd" ]; then | |
| git_root=$(GIT_OPTIONAL_LOCKS=0 git -C "$cwd" rev-parse --show-toplevel 2>/dev/null) | |
| if [ -n "$git_root" ]; then | |
| branch=$(GIT_OPTIONAL_LOCKS=0 git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null \ | |
| || GIT_OPTIONAL_LOCKS=0 git -C "$cwd" rev-parse --short HEAD 2>/dev/null) | |
| if [ -n "$branch" ]; then | |
| # Check for dirty state (fast, no locks) | |
| if GIT_OPTIONAL_LOCKS=0 git -C "$cwd" diff --quiet 2>/dev/null \ | |
| && GIT_OPTIONAL_LOCKS=0 git -C "$cwd" diff --cached --quiet 2>/dev/null; then | |
| pill $'\033[48;5;28m' "$FG_WHITE" " $branch" | |
| else | |
| pill $'\033[48;5;136m' "$FG_BLACK" " $branch *" | |
| fi | |
| fi | |
| fi | |
| fi | |
| # ── Segment: Vim mode ───────────────────────────────────────────────────── | |
| if [ -n "$vim_mode" ]; then | |
| printf ' ' | |
| case "$vim_mode" in | |
| NORMAL) pill "$BG_MAGENTA" "$FG_WHITE" "N" ;; | |
| INSERT) pill "$BG_CYAN" "$FG_BLACK" "I" ;; | |
| *) pill "$BG_DARK" "$FG_GRAY" "$vim_mode" ;; | |
| esac | |
| fi | |
| # ── Separator ───────────────────────────────────────────────────────────── | |
| printf ' %s ' "$SEP" | |
| # ── Segment: Model ──────────────────────────────────────────────────────── | |
| if [ -n "$model" ]; then | |
| # Shorten: "Claude 3.5 Sonnet" → "3.5 Sonnet" | |
| short_model=$(echo "$model" | sed 's/^Claude //') | |
| printf "${FG_MAGENTA}${BOLD}⬡ %s${RESET}" "$short_model" | |
| fi | |
| # ── Segment: Context bar ────────────────────────────────────────────────── | |
| if [ -n "$remaining" ]; then | |
| remaining_int=$(printf '%.0f' "$remaining") | |
| used_int=$((100 - remaining_int)) | |
| # Color based on remaining | |
| if [ "$remaining_int" -le 10 ]; then ctx_color="$FG_RED"; ctx_bg="$BG_RED" | |
| elif [ "$remaining_int" -le 25 ]; then ctx_color="$FG_ORANGE"; ctx_bg="$BG_ORANGE" | |
| elif [ "$remaining_int" -le 50 ]; then ctx_color="$FG_YELLOW"; ctx_bg="$BG_YELLOW" | |
| else ctx_color="$FG_GREEN"; ctx_bg="$BG_GREEN" | |
| fi | |
| # 5-char mini progress bar ▓▓▓░░ | |
| filled=$(( used_int * 5 / 100 )) | |
| empty=$((5 - filled)) | |
| bar="" | |
| for i in $(seq 1 $filled); do bar="${bar}▓"; done | |
| for i in $(seq 1 $empty); do bar="${bar}░"; done | |
| printf ' %s ' "$SEP" | |
| printf "${FG_GRAY}ctx ${RESET}${ctx_color}${bar} %d%%${RESET}" "$remaining_int" | |
| fi | |
| # ── Segment: Rate limits ────────────────────────────────────────────────── | |
| if [ -n "$five_pct" ] || [ -n "$week_pct" ]; then | |
| printf ' %s ' "$SEP" | |
| first=1 | |
| if [ -n "$five_pct" ]; then | |
| pct_int=$(printf '%.0f' "$five_pct") | |
| if [ "$pct_int" -ge 90 ]; then rl_color="$FG_RED" | |
| elif [ "$pct_int" -ge 70 ]; then rl_color="$FG_YELLOW" | |
| else rl_color="$FG_GREEN" | |
| fi | |
| printf "${FG_GRAY}5h${RESET} ${rl_color}%d%%${RESET}" "$pct_int" | |
| first=0 | |
| fi | |
| if [ -n "$week_pct" ]; then | |
| [ "$first" -eq 0 ] && printf "${FG_GRAY} · ${RESET}" | |
| pct_int=$(printf '%.0f' "$week_pct") | |
| if [ "$pct_int" -ge 90 ]; then rl_color="$FG_RED" | |
| elif [ "$pct_int" -ge 70 ]; then rl_color="$FG_YELLOW" | |
| else rl_color="$FG_GREEN" | |
| fi | |
| printf "${FG_GRAY}7d${RESET} ${rl_color}%d%%${RESET}" "$pct_int" | |
| fi | |
| fi | |
| # ── Segment: Caveman badge ──────────────────────────────────────────────── | |
| FLAG="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.caveman-active" | |
| if [ -f "$FLAG" ] && [ ! -L "$FLAG" ]; then | |
| MODE=$(head -c 64 "$FLAG" 2>/dev/null | tr -d '\n\r' | tr '[:upper:]' '[:lower:]') | |
| MODE=$(printf '%s' "$MODE" | tr -cd 'a-z0-9-') | |
| case "$MODE" in | |
| off|lite|full|ultra|wenyan-lite|wenyan|wenyan-full|wenyan-ultra|commit|review|compress) | |
| printf ' %s ' "$SEP" | |
| if [ -z "$MODE" ] || [ "$MODE" = "full" ]; then | |
| pill "$BG_ORANGE" "$FG_WHITE" "🪨 CAVEMAN" | |
| else | |
| SUFFIX=$(printf '%s' "$MODE" | tr '[:lower:]' '[:upper:]') | |
| pill "$BG_ORANGE" "$FG_WHITE" "🪨 $SUFFIX" | |
| fi | |
| SAVINGS_FILE="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.caveman-statusline-suffix" | |
| if [ "${CAVEMAN_STATUSLINE_SAVINGS:-1}" != "0" ] && [ -f "$SAVINGS_FILE" ] && [ ! -L "$SAVINGS_FILE" ]; then | |
| SAVINGS=$(head -c 64 "$SAVINGS_FILE" 2>/dev/null | tr -d '\000-\037') | |
| [ -n "$SAVINGS" ] && printf " ${FG_ORANGE}${SAVINGS}${RESET}" | |
| fi | |
| ;; | |
| esac | |
| fi |
