Skip to content

Instantly share code, notes, and snippets.

@yarinsa
Created September 25, 2025 10:56
Show Gist options
  • Save yarinsa/40f3d06fbdbffa4ad5290558897ee40c to your computer and use it in GitHub Desktop.
Save yarinsa/40f3d06fbdbffa4ad5290558897ee40c to your computer and use it in GitHub Desktop.
Claude Code statusLine with git info, changed files count, and daily token usage tracking
#!/bin/bash
# Read JSON input from Claude Code
input=$(cat)
# Extract values from JSON input
project_dir=$(echo "$input" | jq -r '.workspace.project_dir')
current_dir=$(echo "$input" | jq -r '.workspace.current_dir')
model=$(echo "$input" | jq -r '.model.display_name')
# Get relative path for display
if [ "$current_dir" != "$project_dir" ]; then
rel_path=$(realpath --relative-to="$project_dir" "$current_dir" 2>/dev/null || echo "$(basename "$project_dir")/$(basename "$current_dir")")
else
rel_path=$(basename "$project_dir")
fi
# Git information
if git -C "$current_dir" rev-parse --git-dir >/dev/null 2>&1; then
git_branch=$(git -C "$current_dir" -c core.preloadindex=false -c core.fscache=true -c gc.auto=0 branch --show-current 2>/dev/null || echo 'detached')
git_status=$(git -C "$current_dir" -c core.preloadindex=false -c core.fscache=true -c gc.auto=0 status --porcelain=v1 2>/dev/null)
if [ -n "$git_status" ]; then
git_dirty='*'
changed_count=$(echo "$git_status" | wc -l | tr -d ' ')
git_info=" ($changed_count)"
else
git_dirty=''
git_info=''
fi
git_part="$git_branch$git_dirty$git_info"
else
git_part=""
fi
# Token usage tracking using ccusage
# Cache the usage data for 5 minutes to avoid running ccusage too frequently
cache_file="/tmp/claude_usage_cache"
cache_age=300 # 5 minutes in seconds
# Check if cache exists and is recent
if [ -f "$cache_file" ] && [ $(($(date +%s) - $(stat -f %m "$cache_file" 2>/dev/null || echo 0))) -lt $cache_age ]; then
token_usage=$(cat "$cache_file")
else
# Run ccusage and extract today's usage
today_pattern="$(date +%m-%d)"
usage_output=$(npx --yes ccusage@latest 2>/dev/null | sed 's/\x1b\[[0-9;]*m//g' | grep -B1 "$today_pattern" | head -1)
if [ -n "$usage_output" ] && echo "$usage_output" | grep -q ""; then
# Extract total tokens and cost from today's row
total_tokens=$(echo "$usage_output" | awk -F'' '{print $7}' | tr -d ' ')
daily_cost=$(echo "$usage_output" | awk -F'' '{print $9}' | tr -d ' ')
# Format the usage display (convert to millions for readability)
if [ -n "$total_tokens" ] && [ "$total_tokens" != "" ] && [ "$total_tokens" != "Total" ]; then
# Remove commas and ellipsis for processing
clean_tokens=$(echo "$total_tokens" | sed 's/,//g' | sed 's/…//g')
# Check if it's a truncated number (contains …)
if echo "$total_tokens" | grep -q ""; then
# For truncated numbers like "13,065,…" assume it's in thousands
tokens_m=$(echo "scale=1; $clean_tokens / 1000" | bc 2>/dev/null || echo "0")
else
# For complete numbers, convert to millions
tokens_m=$(echo "scale=1; $clean_tokens / 1000000" | bc 2>/dev/null || echo "0")
fi
# Clean up the cost (remove $ and any extra characters)
clean_cost=$(echo "$daily_cost" | sed 's/\$//g' | sed 's/,//g')
# Format the final display
if [ -n "$clean_cost" ] && [ "$clean_cost" != "" ]; then
token_usage="today: ${tokens_m}M • \$${clean_cost}"
else
token_usage="today: ${tokens_m}M"
fi
echo "$token_usage" > "$cache_file"
else
token_usage="usage unavailable"
fi
else
token_usage="usage unavailable"
fi
fi
# Build status line
if [ -n "$git_part" ]; then
printf '%s %s • %s • %s' "$rel_path" "$git_part" "$model" "$token_usage"
else
printf '%s • %s • %s' "$rel_path" "$model" "$token_usage"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment