Install command
Not provided
A Claude Code statusline script (bash) that reads cost.total_duration_ms from the statusline JSON on stdin via jq, converts it to elapsed minutes, and renders a 20-character progress bar, a percent-used figure, and a countdown against a 300-minute (5-hour) ceiling, with green/yellow/red ANSI color coding at the 50%.
Open the source and read safety notes before installing.
Source-backed facts for citing this resource, derived directly from the registry — also available as plain text for AI assistants.
Decision playbook
Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.
0
78
—
No baseline selected
No major trust-signal divergence detected in the current selection.
Confirm ownership and provenance before trusting install instructions.
Source link availableRequired
Open the canonical repository and verify ownership.
Source provenance statusRequired
Marked as source-backed.
Metadata reviewed
Registry metadata indicates a reviewed listing.
Validate risk disclosures before installation or API wiring.
Safety notes presentRequired
Review the listed safety guidance before running commands.
Privacy notes presentRequired
Review data handling notes before connecting accounts or secrets.
Trust level risk gateRequired
Trust level does not block evaluation.
Check package metadata and artifact integrity signals.
Install payload available
Install or copy payload is available for review.
Package verification flag
No package verification flag provided.
Checksum metadata
No checksum provided for downloaded artifact.
Use compare context to validate trade-offs before adoption.
Compare tray has multiple entries
Add at least one more entry to compare trust differences.
Baseline comparison available
No baseline peer selected yet.
Diverging trust signals identified
No major trust-signal divergence found.
Setup at a glance
Copy-ready — paste the snippet to get started.
Install command
Not provided
Config snippet
Provided
Copy snippet
Provided
Prerequisites
6 to clear
Platforms
1 listed
Difficulty
4/100
Adoption plan
Current risk score 16/100. Use staged verification before broader rollout.
Validate source and review signals before any execution.
Confirm source provenanceRequired
Source URL/provenance metadata is present.
Confirm metadata review state
Listing has review metadata.
Verify install payload
Install/config payload exists and can be inspected.
Confirm safety, privacy, and package integrity signals.
Review safety notesRequired
Safety notes are present.
Review privacy notesRequired
Privacy notes are present.
Verify package integrity metadata
No package verification/checksum metadata.
Adopt in controlled steps based on the selected plan.
Run in isolated sandbox firstRequired
Use a constrained sandbox and observe behavior across multiple tasks.
Roll out graduallyRequired
Roll out to a small cohort before wider usage.
Set monitoring and fallback
Define rollback path and monitor errors after adoption.
Evidence readiness
Required evidence gates are covered (5/6 signals complete).
Source repository/provenance is listed.
Required in this preset
Review metadata is present.
Required in this preset
Safety notes are present.
Required in this preset
Privacy notes are present.
Optional in this preset
Package integrity metadata is missing.
Optional in this preset
Install payload is available.
Required in this preset
Required evidence gates are covered for this preset.
Decision timeline
5/6 steps complete with no blocking gaps for this preset.
triage
Source/provenance metadata is available.
triage
Review metadata is available.
verify
Safety notes are available.
verify
Privacy notes are available.
verify
Package integrity metadata is missing.
rollout
Install payload is available.
No required blockers for this timeline preset.
Prerequisite readiness
6 prerequisites to line up before setup.
Safety & privacy surface
3 safety and 2 privacy notes across 3 risk areas. Review closely: credentials & tokens, permissions & scopes.
#!/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"{
"statusLine": {
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/five-hour-window-tracker.sh",
"refreshInterval": 1000
}
}{
"statusLine": {
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/five-hour-window-tracker.sh",
"refreshInterval": 1000
}
}
Extended version tracking multiple sessions within the 5-hour window
#!/usr/bin/env bash
# Enhanced 5-Hour Window Tracker with Session History
input=$(cat)
session_id=$(echo "$input" | jq -r '.session_id // ""')
total_duration_ms=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
# Session history directory
HISTORY_DIR="${HOME}/.claude-code-windows"
mkdir -p "$HISTORY_DIR"
# Current session file
SESSION_FILE="${HISTORY_DIR}/${session_id}.session"
# Store session start time if new session
if [ ! -f "$SESSION_FILE" ]; then
echo "$(date +%s)" > "$SESSION_FILE"
fi
session_start=$(cat "$SESSION_FILE")
current_time=$(date +%s)
session_elapsed=$(( (current_time - session_start) / 60 ))
# Use actual duration from JSON or calculated elapsed time
duration_minutes=$((total_duration_ms / 60000))
if [ $duration_minutes -eq 0 ]; then
duration_minutes=$session_elapsed
fi
WINDOW_LIMIT=300
time_remaining=$((WINDOW_LIMIT - duration_minutes))
if [ $duration_minutes -gt 0 ]; then
percentage_used=$(( (duration_minutes * 100) / WINDOW_LIMIT ))
else
percentage_used=0
fi
if [ $percentage_used -gt 100 ]; then
percentage_used=100
time_remaining=0
fi
if [ $percentage_used -lt 50 ]; then
STATUS_COLOR="\033[38;5;46m"
STATUS_ICON="✓"
elif [ $percentage_used -lt 80 ]; then
STATUS_COLOR="\033[38;5;226m"
STATUS_ICON="⚠"
else
STATUS_COLOR="\033[38;5;196m"
STATUS_ICON="⏰"
fi
bar_filled=$((percentage_used / 5))
bar_empty=$((20 - bar_filled))
if [ $bar_filled -gt 0 ]; then
bar=$(printf "█%.0s" $(seq 1 $bar_filled))$(printf "░%.0s" $(seq 1 $bar_empty))
else
bar="░░░░░░░░░░░░░░░░░░░░"
fi
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"
echo -e "${STATUS_ICON} 5H Window: ${STATUS_COLOR}${bar}${RESET} ${percentage_used}% | ${STATUS_COLOR}${time_display}${RESET} left"
Configurable window limit for different usage scenarios
#!/usr/bin/env bash
# 5-Hour Window Tracker with Custom Window Limit
# Configurable window limit (default 300 minutes = 5 hours)
WINDOW_LIMIT=${FIVE_HOUR_WINDOW_LIMIT:-300}
input=$(cat)
total_duration_ms=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
duration_minutes=$((total_duration_ms / 60000))
time_remaining=$((WINDOW_LIMIT - duration_minutes))
if [ $duration_minutes -gt 0 ]; then
percentage_used=$(( (duration_minutes * 100) / WINDOW_LIMIT ))
else
percentage_used=0
fi
if [ $percentage_used -gt 100 ]; then
percentage_used=100
time_remaining=0
fi
if [ $percentage_used -lt 50 ]; then
STATUS_COLOR="\033[38;5;46m"
STATUS_ICON="✓"
elif [ $percentage_used -lt 80 ]; then
STATUS_COLOR="\033[38;5;226m"
STATUS_ICON="⚠"
else
STATUS_COLOR="\033[38;5;196m"
STATUS_ICON="⏰"
fi
bar_filled=$((percentage_used / 5))
bar_empty=$((20 - bar_filled))
if [ $bar_filled -gt 0 ]; then
bar=$(printf "█%.0s" $(seq 1 $bar_filled))$(printf "░%.0s" $(seq 1 $bar_empty))
else
bar="░░░░░░░░░░░░░░░░░░░░"
fi
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"
echo -e "${STATUS_ICON} ${WINDOW_LIMIT}min Window: ${STATUS_COLOR}${bar}${RESET} ${percentage_used}% | ${STATUS_COLOR}${time_display}${RESET} left"
Complete setup script with Unicode character verification
#!/bin/bash
# Installation script for Five Hour Window Tracker
mkdir -p .claude/statuslines
# Check for jq (required for JSON parsing)
if ! command -v jq &> /dev/null; then
echo "Installing jq for JSON parsing..."
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install jq
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo apt-get install -y jq || sudo yum install -y jq
else
echo "Please install jq manually: https://jqlang.github.io/jq/"
fi
fi
# Test Unicode block characters
if echo -e '█░' &> /dev/null; then
echo "Unicode block characters supported"
else
echo "Warning: Unicode block characters may not be supported in your terminal"
echo "Script will use Unicode blocks (█ and ░) - if they don't display, consider ASCII alternatives"
fi
cat > .claude/statuslines/five-hour-window-tracker.sh << 'SCRIPT_EOF'
#!/usr/bin/env bash
# 5-Hour Session Window Tracker for Claude Code
# Tracks Claude's unique 5-hour rolling session window
read -r input
total_duration_ms=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
duration_minutes=$((total_duration_ms / 60000))
WINDOW_LIMIT=300
time_remaining=$((WINDOW_LIMIT - duration_minutes))
if [ $duration_minutes -gt 0 ]; then
percentage_used=$(( (duration_minutes * 100) / WINDOW_LIMIT ))
else
percentage_used=0
fi
if [ $percentage_used -gt 100 ]; then
percentage_used=100
time_remaining=0
fi
if [ $percentage_used -lt 50 ]; then
STATUS_COLOR="\033[38;5;46m"
STATUS_ICON="✓"
elif [ $percentage_used -lt 80 ]; then
STATUS_COLOR="\033[38;5;226m"
STATUS_ICON="⚠"
else
STATUS_COLOR="\033[38;5;196m"
STATUS_ICON="⏰"
fi
bar_filled=$((percentage_used / 5))
bar_empty=$((20 - bar_filled))
if [ $bar_filled -gt 0 ]; then
bar=$(printf "█%.0s" $(seq 1 $bar_filled))$(printf "░%.0s" $(seq 1 $bar_empty))
else
bar="░░░░░░░░░░░░░░░░░░░░"
fi
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"
echo -e "${STATUS_ICON} 5H Window: ${STATUS_COLOR}${bar}${RESET} ${percentage_used}% | ${STATUS_COLOR}${time_display}${RESET} left"
SCRIPT_EOF
chmod +x .claude/statuslines/five-hour-window-tracker.sh
# Add to settings.json
if [ ! -f .claude/settings.json ]; then
echo '{"statusLine":{"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/five-hour-window-tracker.sh","refreshInterval":1000}}' > .claude/settings.json
else
jq '.statusLine = {"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/five-hour-window-tracker.sh","refreshInterval":1000}' .claude/settings.json > .claude/settings.json.tmp
mv .claude/settings.json.tmp .claude/settings.json
fi
echo "Five Hour Window Tracker installed successfully!"
echo "Note: This tracks Claude Code's unique 5-hour rolling session window (300 minutes)"
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. Verify printf command works: printf '█%.0s' $(seq 1 5). Check terminal encoding: locale charmap (should be UTF-8).
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. Check WINDOW_LIMIT is 300: echo $WINDOW_LIMIT. Verify time_remaining calculation: time_remaining=$((WINDOW_LIMIT - duration_minutes)).
Script caps percentage at 100% with overflow protection. Sessions can run longer than 300 minutes. If you see 100% + EXPIRED, the session has exceeded the configured ceiling (this is a display ceiling, not Claude's actual usage limit). This is expected behavior, not a bug. Start new session to reset window. Verify percentage calculation: percentage_used=$(( (duration_minutes * 100) / WINDOW_LIMIT )). Check overflow protection: if [ $percentage_used -gt 100 ]; then percentage_used=100; fi.
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. Verify ANSI color codes work: echo -e '\033[38;5;46mGREEN\033[0m'. Check terminal supports 256-color mode: echo $TERM (should be xterm-256color or similar).
Statusline tracks CURRENT session only (based on session_id in JSON). This script reads only the current session's total_duration_ms; it does not aggregate concurrent sessions. To track other sessions, run separate statusline instances or modify the script to read from multiple session files. Verify session_id exists: echo '$input' | jq .session_id. Check if session history tracking is enabled in enhanced version.
Verify time_remaining calculation: time_remaining=$((WINDOW_LIMIT - duration_minutes)). Check hours calculation: remaining_hours=$((time_remaining / 60)). Check minutes calculation: remaining_mins=$((time_remaining % 60)). Test: time_remaining=150 should show '2h 30m'. Verify format logic: if [ $time_remaining -gt 60 ]; then show hours and minutes; elif [ $time_remaining -gt 0 ]; then show minutes only; else show EXPIRED.
Verify bar_filled calculation: bar_filled=$((percentage_used / 5)) (each char = 5%). Test: percentage=50%; bar_filled=$((50 / 5)); echo $bar_filled (should be 10). Check bar_empty calculation: bar_empty=$((20 - bar_filled)). Verify printf command: printf '█%.0s' $(seq 1 5) should output 5 block characters. Ensure seq command is available: which seq.
Check JSON input is being read: echo '$input' | jq .. Verify cost.total_duration_ms exists: echo '$input' | jq .cost.total_duration_ms. Check jq is installed: which jq. Verify duration_minutes calculation: duration_minutes=$((total_duration_ms / 60000)). Test with sample JSON: echo '{"cost":{"total_duration_ms":180000}}' | jq -r '.cost.total_duration_ms // 0' (should return 180000). Check refreshInterval in settings.json is set to 1000ms or lower.
Show that Five Hour Window Tracker - Statuslines is listed on HeyClaude. Paste this Markdown into your README — it renders the badge and links back to this page.
[](https://heyclau.de/entry/statuslines/five-hour-window-tracker)Five Hour Window Tracker - Statuslines side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
| Field | A Claude Code statusline script (bash) that reads cost.total_duration_ms from the statusline JSON on stdin via jq, converts it to elapsed minutes, and renders a 20-character progress bar, a percent-used figure, and a countdown against a 300-minute (5-hour) ceiling, with green/yellow/red ANSI color coding at the 50%. Open dossier | Claude 5-hour conversation block tracker with visual countdown, expiration warnings, and color-coded indicators to prevent unexpected session terminations. Open dossier | Claude Code daily usage quota tracker showing percentage of daily limit consumed with visual progress bar, time remaining, and budget pacing indicators. Open dossier | Multi-provider AI performance dashboard with context occupancy tracking, truncation warnings, TTFT latency, tokens/min rate, and model comparison metrics. Open dossier |
|---|---|---|---|---|
| Next steps | ||||
| Trust | ||||
| Review status | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed |
| Package trust | Package not verified | Package not verified | Package not verified | Package not verified |
| Source provenance | Source-backed | Source-backed | Source-backed | Source-backed |
| Submitter | — | — | — | — |
| Install risk | Review first | Review first | Review first | Review first |
| Notes | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ |
| Brand | — | — | — | — |
| Category | statuslines | statuslines | statuslines | statuslines |
| Source | source-backed | source-backed | source-backed | source-backed |
| Author | JSONbored | JSONbored | JSONbored | JSONbored |
| Added | 2025-10-25 | 2025-10-23 | 2025-10-25 | 2025-10-23 |
| Platforms | Claude Code | Claude Code | Claude Code | Claude Code |
| Source repo | — | — | — | — |
| Safety notes | ✓The installation example runs package-manager commands with elevated privileges (brew install jq, sudo apt-get/yum install jq) and writes an executable script plus statusLine config into .claude/. Review it before running. The installation example overwrites the statusLine key in .claude/settings.json (via a jq rewrite and mv), which replaces any existing statusline configuration. The statusline command executes on every refresh (refreshInterval 1000ms) and shells out to jq and seq each time. | ✓Runs as a Claude Code statusline command on every refresh and depends on the local shell environment; a failure only affects status rendering, not your session. | ✓Runs as a Claude Code statusline command on every refresh and depends on the local shell environment; a failure only affects status rendering, not your session. | ✓Runs as a Claude Code statusline command on every refresh and depends on the local shell environment; a failure only affects status rendering, not your session. |
| Privacy notes | ✓The enhanced example writes per-session timestamp files keyed by session_id into ~/.claude-code-windows on local disk; these persist until manually deleted. The script parses the statusline JSON Claude Code passes on stdin (session_id, cost.total_duration_ms); it stays local and makes no network calls. | ✓Reads the Claude Code statusline JSON from stdin (model, workspace path, token usage) and renders it in the local terminal; it does not send data off-machine. | ✓Reads the Claude Code statusline JSON from stdin (model, workspace path, token usage) and renders it in the local terminal; it does not send data off-machine. | ✓Reads the Claude Code statusline JSON from stdin (model, token usage, context occupancy) and renders it in the local terminal; it does not send data off-machine. |
| Prerequisites |
|
|
|
|
| Install | — | — | — | — |
| Config | | | | |
| Citations | ||||
| Claim | Unclaimed | Unclaimed | Unclaimed | Unclaimed |
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.