Loading...
Claude Code 5-hour rolling session window tracker with visual progress bar, time remaining countdown, and expiry warnings for usage management.
#!/usr/bin/env bash
# 5-Hour Session Window Tracker for Claude Code
# Tracks Claude's unique 5-hour rolling session window
# Read JSON from stdin
read -r input
# Extract session duration in milliseconds
total_duration_ms=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
# Convert to minutes and hours
duration_minutes=$((total_duration_ms / 60000))
duration_hours=$((duration_minutes / 60))
remaining_minutes=$((duration_minutes % 60))
# 5-hour window is 300 minutes
WINDOW_LIMIT=300
time_remaining=$((WINDOW_LIMIT - duration_minutes))
# Calculate percentage of window used
if [ $duration_minutes -gt 0 ]; then
percentage_used=$(( (duration_minutes * 100) / WINDOW_LIMIT ))
else
percentage_used=0
fi
# Prevent overflow (sessions can continue beyond 5 hours in practice)
if [ $percentage_used -gt 100 ]; then
percentage_used=100
time_remaining=0
fi
# Color coding based on window usage
if [ $percentage_used -lt 50 ]; then
STATUS_COLOR="\033[38;5;46m" # Green: < 50% used
STATUS_ICON="✓"
elif [ $percentage_used -lt 80 ]; then
STATUS_COLOR="\033[38;5;226m" # Yellow: 50-80% used
STATUS_ICON="⚠"
else
STATUS_COLOR="\033[38;5;196m" # Red: > 80% used
STATUS_ICON="⏰"
fi
# Build progress bar (20 characters wide)
bar_filled=$(( percentage_used / 5 )) # Each char = 5%
bar_empty=$(( 20 - bar_filled ))
bar=$(printf "█%.0s" $(seq 1 $bar_filled))$(printf "░%.0s" $(seq 1 $bar_empty))
# Format time remaining
if [ $time_remaining -gt 60 ]; then
remaining_hours=$((time_remaining / 60))
remaining_mins=$((time_remaining % 60))
time_display="${remaining_hours}h ${remaining_mins}m"
elif [ $time_remaining -gt 0 ]; then
time_display="${time_remaining}m"
else
time_display="EXPIRED"
fi
RESET="\033[0m"
# Output statusline
echo -e "${STATUS_ICON} 5H Window: ${STATUS_COLOR}${bar}${RESET} ${percentage_used}% | ${STATUS_COLOR}${time_display}${RESET} left"{
"format": "bash",
"position": "left",
"refreshInterval": 1000
}Progress bar not updating or showing as empty boxes
Ensure terminal supports Unicode block characters (█ and ░). Test with: echo -e '█████░░░░░'. If unsupported, replace with ASCII: bar_filled uses '#' and bar_empty uses '-' instead of Unicode blocks.
Time remaining showing negative or EXPIRED incorrectly
Check cost.total_duration_ms field in JSON: echo '$input' | jq .cost.total_duration_ms. Verify calculation: duration_minutes should be total_duration_ms / 60000. If sessions overlap, this tracks CURRENT session only, not aggregate time.
Percentage exceeds 100% showing incorrect progress
Script caps percentage at 100% with overflow protection. Claude sessions can continue beyond 5 hours in practice. If you see 100% + EXPIRED, session has exceeded window. This is expected behavior, not a bug. Start new session to reset window.
Warning colors not displaying at correct thresholds
Verify color thresholds: <50% green, 50-80% yellow, >80% red. Check percentage_used calculation: (duration_minutes * 100) / 300. Test with known durations: 150 min should be 50% yellow, 250 min should be 83% red.
Multiple overlapping sessions not reflected in tracker
Statusline tracks CURRENT session only (based on session_id in JSON). Claude supports multiple overlapping 5-hour windows simultaneously. To track multiple sessions, run separate statusline instances or modify script to read from multiple session files.
Loading reviews...