Skip to content

Instantly share code, notes, and snippets.

@jeremyronking
Last active January 19, 2026 07:01
Show Gist options
  • Select an option

  • Save jeremyronking/7dc1978531b36a4d3741d2faef553a8e to your computer and use it in GitHub Desktop.

Select an option

Save jeremyronking/7dc1978531b36a4d3741d2faef553a8e to your computer and use it in GitHub Desktop.
Claude Code Status Line - Enhanced statusline showing model, mode, context usage, API limits with reset times, and git branch
#!/bin/bash
# ==============================================================================
# Claude Code Status Line
# ==============================================================================
# This script creates a rich status line for Claude Code showing:
# - Current model being used
# - Mode (if in plan/edit mode)
# - Context window usage percentage
# - API usage limits (5-hour and 7-day windows) with time until reset
# - Current git branch
#
# Usage: Configure this script in your Claude Code settings as a statusline hook
# Requirements: jq, curl, git (optional)
#
# The script expects JSON input from Claude Code via stdin
# ==============================================================================
input=$(cat)
# ==============================================================================
# Extract Model Information
# ==============================================================================
MODEL=$(echo "$input" | jq -r '.model.display_name // "Unknown"')
# ==============================================================================
# API Usage Limits Fetching (with caching)
# ==============================================================================
# Fetches usage data from Anthropic API and caches it to avoid rate limiting
# Cache expires after 60 seconds to keep data reasonably fresh
CACHE_FILE="/tmp/claude-usage-cache"
CACHE_MAX_AGE=60
fetch_usage_limits() {
# Retrieves OAuth credentials from macOS Keychain and fetches usage data
# Note: This uses macOS 'security' command - may need adjustment for Linux
local creds token
creds=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)
if [ -z "$creds" ]; then
echo ""
return
fi
# Extract OAuth access token from credentials JSON
token=$(echo "$creds" | jq -r '.claudeAiOauth.accessToken // empty')
if [ -z "$token" ]; then
echo ""
return
fi
# Query Anthropic API for usage statistics (5-hour and 7-day windows)
curl -s --max-time 2 -H "Authorization: Bearer $token" \
-H "anthropic-beta: oauth-2025-04-20" \
https://api.anthropic.com/api/oauth/usage
}
get_usage_limits() {
# Returns cached usage data if fresh, otherwise fetches new data
# This prevents hammering the API on every statusline refresh
if [ -f "$CACHE_FILE" ]; then
local cache_age=$(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0)))
if [ "$cache_age" -lt "$CACHE_MAX_AGE" ]; then
cat "$CACHE_FILE"
return
fi
fi
# Cache is stale or missing - fetch fresh data
local data
data=$(fetch_usage_limits)
if [ -n "$data" ]; then
echo "$data" > "$CACHE_FILE"
echo "$data"
fi
}
# ==============================================================================
# Time Formatting Helper
# ==============================================================================
# Converts ISO 8601 timestamp to human-readable relative time
# Examples: "2h30m", "3d5h", "45m", "now"
format_time_until() {
local reset_at="$1"
if [ -z "$reset_at" ] || [ "$reset_at" = "null" ]; then
echo ""
return
fi
# Parse ISO timestamp (e.g., "2025-12-31T23:59:59.000Z") and convert to epoch
# Note: Uses macOS 'date -j' format - may need adjustment for GNU date
local reset_epoch now_epoch diff
reset_epoch=$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%S" "${reset_at%%.*}" "+%s" 2>/dev/null)
if [ -z "$reset_epoch" ]; then
echo ""
return
fi
now_epoch=$(date +%s)
diff=$((reset_epoch - now_epoch))
if [ "$diff" -le 0 ]; then
echo "now"
return
fi
# Calculate days, hours, and minutes
local days hours mins
days=$((diff / 86400))
hours=$(((diff % 86400) / 3600))
mins=$(((diff % 3600) / 60))
# Format output based on magnitude (show top 2 units)
if [ "$days" -gt 0 ]; then
echo "${days}d${hours}h"
elif [ "$hours" -gt 0 ]; then
echo "${hours}h${mins}m"
else
echo "${mins}m"
fi
}
# Fetch usage limits from API
USAGE_LIMITS=$(get_usage_limits)
# ==============================================================================
# Extract Mode Information
# ==============================================================================
# Mode shows if Claude is in a special state (e.g., "plan", "edit")
MODE=$(echo "$input" | jq -r '.mode // empty')
if [ -z "$MODE" ]; then
MODE_DISPLAY=""
else
MODE_DISPLAY=" | ${MODE} |"
fi
# ==============================================================================
# Context Window Usage Calculation
# ==============================================================================
# Calculate percentage of context window used (including cache tokens)
CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
USAGE=$(echo "$input" | jq '.context_window.current_usage // null')
if [ "$USAGE" != "null" ]; then
# Sum all token types: regular input, cache creation, and cache reads
CURRENT=$(echo "$USAGE" | jq '.input_tokens + .cache_creation_input_tokens + .cache_read_input_tokens')
PERCENT=$((CURRENT * 100 / CONTEXT_SIZE))
else
PERCENT=0
fi
# ==============================================================================
# Color Coding Helper
# ==============================================================================
# Returns ANSI color code based on usage percentage
# Green (0-59%), Yellow (60-79%), Red (80-100%)
get_color() {
local pct=$1
if [ "$pct" -ge 80 ]; then
echo "\033[31m" # Red
elif [ "$pct" -ge 60 ]; then
echo "\033[33m" # Yellow
else
echo "\033[32m" # Green
fi
}
# ==============================================================================
# ANSI Color Codes
# ==============================================================================
RESET="\033[0m"
CYAN="\033[36m"
MAGENTA="\033[35m"
WHITE="\033[97m"
# Apply color to context percentage
CTX_COLOR=$(get_color "$PERCENT")
# ==============================================================================
# Parse API Usage Limits
# ==============================================================================
# Anthropic enforces two rate limit windows:
# - 5-hour rolling window
# - 7-day rolling window
# This section displays both usage percentages with time until reset
if [ -n "$USAGE_LIMITS" ]; then
# Extract utilization percentages (strip decimal places)
FIVE_HOUR=$(echo "$USAGE_LIMITS" | jq -r '.five_hour.utilization // empty' | cut -d. -f1)
SEVEN_DAY=$(echo "$USAGE_LIMITS" | jq -r '.seven_day.utilization // empty' | cut -d. -f1)
FIVE_RESET=$(echo "$USAGE_LIMITS" | jq -r '.five_hour.resets_at // empty')
SEVEN_RESET=$(echo "$USAGE_LIMITS" | jq -r '.seven_day.resets_at // empty')
if [ -n "$FIVE_HOUR" ] && [ -n "$SEVEN_DAY" ]; then
# Apply color coding to each limit
FIVE_COLOR=$(get_color "$FIVE_HOUR")
SEVEN_COLOR=$(get_color "$SEVEN_DAY")
# Convert reset timestamps to human-readable format
FIVE_TIME=$(format_time_until "$FIVE_RESET")
SEVEN_TIME=$(format_time_until "$SEVEN_RESET")
# Build display strings with colored percentages and reset times
FIVE_DISPLAY="5h: ${FIVE_COLOR}${FIVE_HOUR}%${RESET}"
[ -n "$FIVE_TIME" ] && FIVE_DISPLAY="${FIVE_DISPLAY} → ${MAGENTA}${FIVE_TIME}${RESET}"
SEVEN_DISPLAY="7d: ${SEVEN_COLOR}${SEVEN_DAY}%${RESET}"
[ -n "$SEVEN_TIME" ] && SEVEN_DISPLAY="${SEVEN_DISPLAY} → ${MAGENTA}${SEVEN_TIME}${RESET}"
LIMITS_DISPLAY=" | ${FIVE_DISPLAY} | ${SEVEN_DISPLAY}"
else
LIMITS_DISPLAY=""
fi
else
LIMITS_DISPLAY=""
fi
# ==============================================================================
# Git Branch Detection
# ==============================================================================
# Shows current git branch if working directory is in a git repository
GIT_BRANCH=""
if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
if [ -n "$BRANCH" ]; then
GIT_BRANCH=" | ${CYAN}${BRANCH}${RESET}"
fi
fi
# ==============================================================================
# Final Output
# ==============================================================================
# Assemble all components into final statusline
# Format: [Model] | mode | Context: XX% | 5h: XX% → Xh | 7d: XX% → Xd | branch
echo -e "[${MODEL}]${MODE_DISPLAY} ${WHITE}Context:${RESET} ${CTX_COLOR}${PERCENT}%${RESET}${LIMITS_DISPLAY}${GIT_BRANCH}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment