Created
June 23, 2026 17:01
-
-
Save RickMcKay777/d3efaace9f06e92f4f087236a04582ec to your computer and use it in GitHub Desktop.
Claude Status Bar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Claude Code custom status line — two lines: | |
| # Line 1: folder + full path + git branch (if in a repo) + [model ctx:%] (left) | |
| # Line 2: 5-hour and 7-day usage with color-coded bars + reset countdowns (right-aligned) | |
| # | |
| # Reads the JSON Claude Code pipes to it on stdin. Requires: jq, GNU sed, wc, date. | |
| # Right-alignment uses the COLUMNS env var (Claude Code sets it on v2.1.153+). | |
| # | |
| # Install: | |
| # 1. Save this file (e.g. ~/.claude/statusline.sh) | |
| # 2. settings.json: "command": "bash ~/.claude/statusline.sh" | |
| # 3. If settings point at statusline-command.sh, copy it over: | |
| # cp ~/.claude/statusline.sh ~/.claude/statusline-command.sh | |
| # 4. Restart Claude Code and send one message. | |
| input=$(cat) | |
| MODEL=$(echo "$input" | jq -r '.model.display_name // "Claude"') | |
| CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) | |
| DIR=$(echo "$input" | jq -r '.workspace.current_dir // ""') | |
| FIVE=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty') | |
| WEEK=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty') | |
| FIVE_R=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty') | |
| WEEK_R=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty') | |
| IN=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0') | |
| OUT=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0') | |
| G=$'\033[32m'; Y=$'\033[33m'; R=$'\033[31m' | |
| C=$'\033[36m'; M=$'\033[35m'; D=$'\033[2m'; X=$'\033[0m' | |
| DOT=$'\033[2m' # dot-leader color: dim (your terminal renders dim as DARK) | |
| REM=$'\033[30m' # remaining-time color: ANSI black (your terminal renders this LIGHT GRAY) | |
| pick() { local p=$1; if [ "$p" -ge 80 ]; then echo "$R"; elif [ "$p" -ge 50 ]; then echo "$Y"; else echo "$G"; fi; } | |
| bar() { | |
| local p=$1 w=6 f e fill pad | |
| f=$((p * w / 100)); [ "$f" -gt "$w" ] && f=$w; e=$((w - f)) | |
| [ "$f" -gt 0 ] && printf -v fill "%${f}s" || fill="" | |
| [ "$e" -gt 0 ] && printf -v pad "%${e}s" || pad="" | |
| printf "%s%s" "${fill// /▓}" "${pad// /░}" | |
| } | |
| reset() { | |
| local t=$1 now diff | |
| [ -z "$t" ] && return | |
| now=$(date +%s); diff=$((t - now)); [ "$diff" -lt 0 ] && diff=0 | |
| if [ "$diff" -lt 86400 ]; then | |
| printf "%dh%02dm" $((diff/3600)) $(((diff%3600)/60)) | |
| else | |
| date -d "@$t" +"%a %Hh" 2>/dev/null | |
| fi | |
| } | |
| # Locale-INDEPENDENT visible width in columns: strip ANSI, then collapse each | |
| # known multi-byte glyph to one ASCII byte so a plain byte count == column count. | |
| viswidth() { | |
| printf '%s' "$1" \ | |
| | LC_ALL=C sed -e 's/\x1b\[[0-9;]*m//g' \ | |
| -e 's/▓/./g; s/░/./g; s/↻/./g; s/│/./g' \ | |
| | LC_ALL=C wc -c | |
| } | |
| BRANCH="" | |
| if git -C "$DIR" rev-parse --git-dir >/dev/null 2>&1; then | |
| BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null) | |
| fi | |
| # --- Line 1 --- | |
| LINE1="${C}📁 ${DIR}${X}" | |
| [ -n "$BRANCH" ] && LINE1="${LINE1} ${M}⎇ ${BRANCH}${X}" | |
| LINE1="${LINE1} ${D}[${X}${MODEL} ctx:$(pick "$CTX")${CTX}%${X}${D}]${X}" | |
| # --- Line 2 --- | |
| LINE2="printf '🧠 %dk in / %dk out' $((IN/1000)) $((OUT/1000))" | |
| if [ -n "$FIVE" ]; then | |
| FP=$(printf '%.0f' "$FIVE") | |
| LINE2="5h $(pick "$FP")$(bar "$FP") ${FP}%${X}${REM} ↻ $(reset "$FIVE_R")${X}" | |
| fi | |
| if [ -n "$WEEK" ]; then | |
| WP=$(printf '%.0f' "$WEEK") | |
| [ -n "$LINE2" ] && LINE2="${LINE2}${D} │ ${X}" | |
| LINE2="${LINE2}7d $(pick "$WP")$(bar "$WP") ${WP}%${X}${REM} ↻ $(reset "$WEEK_R")${X}" | |
| fi | |
| # --- Alignment for line 2 --- | |
| RMARGIN=4 # right-edge gap; raise if line 2 is clipped, lower if gap too big | |
| COLS=$(( ${COLUMNS:-80} - RMARGIN )); [ "$COLS" -lt 1 ] && COLS=1 | |
| WIDTH=0; PAD=0 | |
| if [ -n "$LINE2" ]; then | |
| WIDTH=$(viswidth "$LINE2" | tr -d ' ') | |
| PAD=$((COLS - WIDTH)); [ "$PAD" -lt 0 ] && PAD=0 | |
| fi | |
| # --- Output --- | |
| # Pad with a dim dot leader ('.'): visible (non-whitespace) so Claude Code won't | |
| # strip it, pushing line 2 to the right edge. Recomputed from COLUMNS each render. | |
| printf '%s\n' "$LINE1" | |
| if [ -n "$LINE2" ]; then | |
| SP="" | |
| if [ "$PAD" -gt 0 ]; then | |
| printf -v SP "%${PAD}s" "" | |
| SP="${DOT}${SP// /.}${X}" # darker dot leader (color set by $DOT above) | |
| fi | |
| printf '%s%s\n' "$SP" "$LINE2" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment