Last active
July 15, 2026 13:09
-
-
Save bartolsthoorn/83011e2e1c7d02f670e690a3d2bbc497 to your computer and use it in GitHub Desktop.
Place this in ~/.claude/statusline-command.sh
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
| #!/usr/bin/env bash | |
| # Claude Code status line: branch | dir | model·effort | ctx | 5h / 7d usage limits | |
| input=$(cat) | |
| # --- helpers --------------------------------------------------------------- | |
| # ANSI color for a 0-100 percentage: green < 50, yellow 50-79, red >= 80 | |
| pct_color() { | |
| local p=$1 | |
| if [ "$p" -ge 80 ]; then printf '%s' '\033[31m' | |
| elif [ "$p" -ge 50 ]; then printf '%s' '\033[33m' | |
| else printf '%s' '\033[32m' | |
| fi | |
| } | |
| # Seconds-from-now -> compact human string (3d / 2h10m / 45m / <1m / now) | |
| fmt_eta() { | |
| local secs=$1 | |
| if [ "$secs" -le 0 ]; then printf 'now' | |
| elif [ "$secs" -ge 86400 ]; then printf '%dd' $((secs / 86400)) | |
| elif [ "$secs" -ge 3600 ]; then | |
| local h=$((secs / 3600)) m=$(((secs % 3600) / 60)) | |
| if [ "$m" -gt 0 ]; then printf '%dh%dm' "$h" "$m"; else printf '%dh' "$h"; fi | |
| elif [ "$secs" -ge 60 ]; then printf '%dm' $((secs / 60)) | |
| else printf '<1m' | |
| fi | |
| } | |
| # True when a jq-extracted field is usable (non-empty and not the "-" sentinel) | |
| has_val() { [ -n "$1" ] && [ "$1" != "-" ]; } | |
| # --- read fields (single jq pass) ------------------------------------------ | |
| IFS=$'\t' read -r cur_dir model effort used fh_pct fh_reset sd_pct sd_reset < <( | |
| echo "$input" | jq -r ' | |
| [ (.workspace.current_dir // .cwd // "."), | |
| (.model.display_name // "?"), | |
| (.effort.level // "-"), | |
| (.context_window.used_percentage // "-"), | |
| (.rate_limits.five_hour.used_percentage // "-"), | |
| (.rate_limits.five_hour.resets_at // "-"), | |
| (.rate_limits.seven_day.used_percentage // "-"), | |
| (.rate_limits.seven_day.resets_at // "-") | |
| ] | @tsv' | |
| ) | |
| branch=$(git -C "$cur_dir" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null) | |
| dir=$(basename "$cur_dir") | |
| now=$(date +%s) | |
| parts=() | |
| # branch (cyan, nerd-font glyph) | |
| [ -n "$branch" ] && parts+=("$(printf '\033[36m\xef\x9c\xa0 %s\033[0m' "$branch")") | |
| # working dir (yellow) | |
| parts+=("$(printf '\033[33m%s\033[0m' "$dir")") | |
| # model + effort (gray, middle-dot separated) | |
| if has_val "$effort"; then | |
| parts+=("$(printf '\033[90m%s·%s\033[0m' "$model" "$effort")") | |
| else | |
| parts+=("$(printf '\033[90m%s\033[0m' "$model")") | |
| fi | |
| # context window usage | |
| if has_val "$used"; then | |
| used_int=$(printf '%.0f' "$used") | |
| parts+=("$(printf "$(pct_color "$used_int")ctx:%s%%\033[0m" "$used_int")") | |
| fi | |
| # usage limits (Pro/Max only; populated after the first API response) | |
| limit_seg="" | |
| if has_val "$fh_pct"; then | |
| fh_int=$(printf '%.0f' "$fh_pct") | |
| limit_seg="$(printf "$(pct_color "$fh_int")5h:%s%%\033[0m" "$fh_int")" | |
| has_val "$fh_reset" && limit_seg+="$(printf '\033[90m \xe2\x86\xbb%s\033[0m' "$(fmt_eta $((fh_reset - now)))")" | |
| fi | |
| if has_val "$sd_pct"; then | |
| sd_int=$(printf '%.0f' "$sd_pct") | |
| sd_seg="$(printf "$(pct_color "$sd_int")7d:%s%%\033[0m" "$sd_int")" | |
| has_val "$sd_reset" && sd_seg+="$(printf '\033[90m \xe2\x86\xbb%s\033[0m' "$(fmt_eta $((sd_reset - now)))")" | |
| if [ -n "$limit_seg" ]; then limit_seg+=" $sd_seg"; else limit_seg="$sd_seg"; fi | |
| fi | |
| [ -n "$limit_seg" ] && parts+=("$limit_seg") | |
| # --- join with a dim pipe separator ---------------------------------------- | |
| sep=$(printf ' \033[90m|\033[0m ') | |
| out="" | |
| for p in "${parts[@]}"; do | |
| if [ -n "$out" ]; then out+="$sep"; fi | |
| out+="$p" | |
| done | |
| printf '%s' "$out" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment