Last active
March 2, 2026 19:33
-
-
Save matsubo/463b7f28fcc25dfc7ed114dd93495aca to your computer and use it in GitHub Desktop.
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 | |
| # tmux-claude.sh — Claude Code usage for tmux status bar | |
| # Compact 5-char progress bars with color coding | |
| # Format: ██░░░22% █░░░░14% | |
| CACHE="/tmp/tmux-claude-cache" | |
| LOCK="/tmp/tmux-claude-lock" | |
| CREDS="$HOME/.claude/.credentials.json" | |
| MAX_AGE=300 | |
| GREEN="#a6da95" | |
| YELLOW="#eed49f" | |
| RED="#ed8796" | |
| DIM="#7a839e" | |
| LABEL="#769ff0" | |
| color_for_pct() { | |
| local pct=$1 | |
| if [ "$pct" -lt 50 ]; then echo "$GREEN" | |
| elif [ "$pct" -lt 80 ]; then echo "$YELLOW" | |
| else echo "$RED" | |
| fi | |
| } | |
| make_bar() { | |
| local pct=$1 width=5 | |
| local filled=$(( (pct * width + 50) / 100 )) | |
| [ "$filled" -gt "$width" ] && filled=$width | |
| local empty=$((width - filled)) | |
| local bar="" | |
| for ((i=0; i<filled; i++)); do bar+="█"; done | |
| for ((i=0; i<empty; i++)); do bar+="░"; done | |
| echo "$bar" | |
| } | |
| format_segment() { | |
| local pct=$1 | |
| local color bar filled empty fill_part empty_part | |
| color=$(color_for_pct "$pct") | |
| bar=$(make_bar "$pct") | |
| filled=$(( (pct * 5 + 50) / 100 )) | |
| [ "$filled" -gt 5 ] && filled=5 | |
| empty=$((5 - filled)) | |
| fill_part="${bar:0:$filled}" | |
| empty_part="${bar:$filled:$empty}" | |
| printf "#[fg=%s]%s#[fg=%s]%s#[fg=%s]%d%%" \ | |
| "$color" "$fill_part" "$DIM" "$empty_part" "$color" "$pct" | |
| } | |
| fetch_usage() { | |
| if [ ! -f "$CREDS" ]; then echo "-"; return; fi | |
| local token | |
| token=$(jq -r '.claudeAiOauth.accessToken // empty' "$CREDS") | |
| if [ -z "$token" ]; then echo "-"; return; fi | |
| local json | |
| json=$(curl -s --max-time 5 \ | |
| -H "Authorization: Bearer $token" \ | |
| -H "anthropic-beta: oauth-2025-04-20" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.anthropic.com/api/oauth/usage" 2>/dev/null) | |
| if [ -z "$json" ]; then echo "-"; return; fi | |
| local s_pct w_pct | |
| s_pct=$(echo "$json" | jq -r '.five_hour.utilization // empty' | xargs printf '%.0f' 2>/dev/null) | |
| w_pct=$(echo "$json" | jq -r '.seven_day.utilization // empty' | xargs printf '%.0f' 2>/dev/null) | |
| if [ -z "$s_pct" ] || [ -z "$w_pct" ]; then echo "-"; return; fi | |
| echo "$s_pct $w_pct" > "$PCT_CACHE" | |
| printf "#[fg=%s] %s %s\n" \ | |
| "$LABEL" "$(format_segment "$s_pct")" "$(format_segment "$w_pct")" | |
| } | |
| PCT_CACHE="/tmp/tmux-claude-pct" | |
| compact_output() { | |
| if [ -f "$PCT_CACHE" ]; then | |
| local s_pct w_pct | |
| read -r s_pct w_pct < "$PCT_CACHE" | |
| if [ -n "$s_pct" ] && [ -n "$w_pct" ]; then | |
| local s_color w_color | |
| s_color=$(color_for_pct "$s_pct") | |
| w_color=$(color_for_pct "$w_pct") | |
| printf "#[fg=%s]%d%%#[fg=%s]/#[fg=%s]%d%%" "$s_color" "$s_pct" "$DIM" "$w_color" "$w_pct" | |
| return | |
| fi | |
| fi | |
| echo "-" | |
| } | |
| # Cache logic | |
| if [ -f "$CACHE" ]; then | |
| cached=$(cat "$CACHE") | |
| age=$(( $(date +%s) - $(stat -c %Y "$CACHE") )) | |
| else | |
| cached="" | |
| age=$((MAX_AGE + 1)) | |
| fi | |
| if [ "$age" -le "$MAX_AGE" ]; then | |
| if [ "$1" = "--compact" ]; then compact_output; else echo "$cached"; fi | |
| elif [ -n "$cached" ]; then | |
| if [ "$1" = "--compact" ]; then compact_output; else echo "$cached"; fi | |
| if mkdir "$LOCK" 2>/dev/null; then | |
| ( | |
| trap 'rmdir "$LOCK" 2>/dev/null' EXIT | |
| result=$(fetch_usage) | |
| echo "$result" > "$CACHE" | |
| ) & | |
| fi | |
| else | |
| result=$(fetch_usage) | |
| echo "$result" > "$CACHE" | |
| if [ "$1" = "--compact" ]; then compact_output; else echo "$result"; fi | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment