▸ // spis treści
Limit 5h w Claude Code nie mówi ci, czy pracujesz za szybko. Mówi tylko, ile już zużyłeś. Dołożyłem do paska stanu jedną kreskę, która pokazuje, ile czasu z okna minęło, i od razu widzę, czy mogę przycisnąć, czy lepiej zwolnić.
Zajęło mi to 15 minut, a pasek mam przed oczami przy każdej wiadomości.
Z tego artykułu dowiesz się:
- jak czytać limit 5h i 7d na tle upływu czasu, a nie jako gołą liczbę,
- kiedy cache zaraz wygaśnie i dlaczego wtedy warto napisać od razu,
- jak wkleić gotowy skrypt i mieć ten sam pasek u siebie,
- na czym można się potknąć przy instalacji.
Problem
Goła liczba „32% limitu 5h" nic nie znaczy. Po 4 godzinach okna to świetny wynik. Po 30 minutach - sygnał, że za godzinę staniesz.
Patrzysz na procent i nie pamiętasz, kiedy okno się zaczęło. A Claude Code ma te dane. Przekazuje do paska stanu procent zużycia i dokładny czas resetu obu okien. Wystarczy je zestawić.
Co pokazuje pasek

Ten sam pasek w formie tekstowej, w sześciu sytuacjach:
Wszystko zielone - możesz cisnąć
_Brain_ Opus 5.5 high │ ◷ 48m │ ⛁ 18% · 5h ━───┃─────── 12% 3h0m · 7d ━━───┃────── 20% 3d12h
5h na czerwono - zużycie wyprzedza czas
_Brain_ Opus 5.5 high │ ◷ 35m │ ⛁ 41% · 5h ━━━━┃━━━──── 70% 3h0m · 7d ━━━━┃─────── 30% 4d4h
Równo z czasem - trzymaj tempo
_Brain_ Opus 5.5 high │ ◷ 22m │ ⛁ 27% · 5h ━━━━┃─────── 38% 3h0m · 7d ━━━━━┃────── 52% 3d12h
Cache kończy się za 7 minut
_Brain_ Opus 5.5 high │ ◷ 7m │ ⛁ 33% · 5h ━━━────┃──── 25% 2h0m · 7d ━━━━─┃────── 35% 3d18h
Cache zimny
_Brain_ Opus 5.5 high │ ☠☠ │ ⛁ 22% · 5h ━━┃───────── 18% 4h0m · 7d ━━━━━─┃───── 40% 2d22h
Pełny kontekst i duży commit do zrobienia
_Brain_ Opus 5.5 high │ ◷ 41m │ ⛁ 72% · 5h ━━━━─┃────── 30% 2h30m · 7d ━━━━━─┃───── 45% 3d8h │ +1.2k -340| Element | Co znaczy | Kolory |
|---|---|---|
Opus 5.5 high | model i poziom rozumowania, zmienia się po /effort | - |
◷ 48m | ile minut zostało do wygaśnięcia cache | zielony powyżej 30, żółty 11-30, czerwony 10 i mniej |
☠☠ | cache zimny | czerwony |
⛁ 18% | ile kontekstu jest zajęte | zielony do 30%, żółty do 60%, czerwony powyżej |
5h ━━┃── | gruba linia to zużycie, kreska to czas, który minął z okna | zielony, gdy jesteś ponad 5 punktów przed kreską, żółty w granicach 5 punktów, czerwony, gdy wyprzedzasz kreskę o więcej niż 5 |
+1.2k -340 | linie dodane i usunięte od ostatniego commita | zielony i czerwony |
Kreska rozwiązuje cały problem. Okno 5h, do resetu zostały 3 godziny, więc minęło 40% czasu. Zużyłeś 70%? Pasek robi się czerwony i wiesz, że tniesz za szybko. Zużyłeś 12%? Zielono, możesz odpalić cięższe zadanie.
Cache działa podobnie. Gdy wygaśnie, Claude przelicza całą rozmowę od nowa, a to mocniej zjada limit. Czerwone ◷ 7m to sygnał: pisz teraz albo zrób przerwę świadomie.
Instalacja krok po kroku
- Zainstaluj jq, którym skrypt czyta dane z Claude Code:
brew install jqna macOS. - Zapisz skrypt poniżej jako
~/.claude/statusline.sh. - Dopisz do
~/.claude/settings.json:
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline.sh",
"refreshInterval": 60
}refreshInterval odświeża pasek co 60 sekund, więc kreska i minuty cache przesuwają się też wtedy, gdy nic nie piszesz. Skrypt działa lokalnie i nie zużywa tokenów - tak podaje dokumentacja Claude Code.
Pełny skrypt:
#!/usr/bin/env bash
# Skrypt linii statusu dla Claude Code
# Format: <project> <model_short> <effort> │ ◷ <min> │ ⛁ <pct>% · 5h <pasek> <pct>% <reset> · 7d <pasek> <pct>% <reset> │ +<dodane> -<usunięte>
# Pasek 5h/7d: gruba linia = zużycie, ┃ = ile czasu z okna minęło.
# Kolor 5h/7d: zielony > 5 pkt przed kreską, żółty ±5 pkt, czerwony > 5 pkt za kreską.
input=$(cat)
# Kolory ANSI
DIM="\033[2m"
GRAY="\033[90m"
WHITE="\033[97m"
CYAN="\033[96m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
RESET="\033[0m"
BAR_WIDTH=12
# Kolor limitu bez czasu resetu, na podstawie procentu (liczba całkowita)
pct_color() {
local pct=$1
if [ "$pct" -lt 50 ]; then
printf "%s" "$GREEN"
elif [ "$pct" -le 80 ]; then
printf "%s" "$YELLOW"
else
printf "%s" "$RED"
fi
}
# Kolor kontekstu: do 30% zielony, do 60% żółty, powyżej czerwony
ctx_color() {
local pct=$1
if [ "$pct" -le 30 ]; then
printf "%s" "$GREEN"
elif [ "$pct" -le 60 ]; then
printf "%s" "$YELLOW"
else
printf "%s" "$RED"
fi
}
# Kolor limitu: zużycie względem upływu czasu (punkty procentowe)
pace_color() {
local used=$1 elapsed=$2
local diff=$(( used - elapsed ))
if [ "$diff" -lt -5 ]; then
printf "%s" "$GREEN"
elif [ "$diff" -le 5 ]; then
printf "%s" "$YELLOW"
else
printf "%s" "$RED"
fi
}
# Rysuje pasek: bar <used_pct> <marker_pct albo -1> <kolor>
bar() {
local used=$1 marker=$2 color=$3
local filled=$(( (used * BAR_WIDTH + 50) / 100 ))
[ "$filled" -gt "$BAR_WIDTH" ] && filled=$BAR_WIDTH
local mark=-1
if [ "$marker" -ge 0 ]; then
mark=$(( marker * BAR_WIDTH / 100 ))
[ "$mark" -ge "$BAR_WIDTH" ] && mark=$(( BAR_WIDTH - 1 ))
fi
local out="" i
for (( i = 0; i < BAR_WIDTH; i++ )); do
if [ "$i" -eq "$mark" ]; then
out="${out}${WHITE}┃"
elif [ "$i" -lt "$filled" ]; then
out="${out}${color}━"
else
out="${out}${GRAY}─"
fi
done
printf "%s" "${out}${RESET}"
}
# Formatuje sekundy jako "Xd Yh" lub "XhYm" lub "Xm"
format_remaining() {
local secs=$1
if [ "$secs" -le 0 ]; then
echo "now"
return
fi
local days=$(( secs / 86400 ))
local hours=$(( (secs % 86400) / 3600 ))
local mins=$(( (secs % 3600) / 60 ))
if [ "$days" -ge 1 ]; then
echo "${days}d${hours}h"
elif [ "$hours" -ge 1 ]; then
echo "${hours}h${mins}m"
else
echo "${mins}m"
fi
}
# Nazwa projektu (ostatni element ścieżki katalogu roboczego)
dir=$(echo "$input" | jq -r '.workspace.current_dir // empty')
project=""
if [ -n "$dir" ]; then
project=$(basename "$dir")
fi
# Skrócona nazwa modelu: "Claude X.Y Sonnet" → "Sonnet X.Y", "Haiku" → "Haiku", itd.
model_full=$(echo "$input" | jq -r '.model.display_name // empty')
model_short=""
if [ -n "$model_full" ]; then
# Wyciągnij numer wersji (np. "3.5", "4.6", "3")
version=$(echo "$model_full" | grep -oE '[0-9]+\.[0-9]+|[0-9]+' | head -1)
if echo "$model_full" | grep -qi "sonnet"; then
model_short="Sonnet"
elif echo "$model_full" | grep -qi "haiku"; then
model_short="Haiku"
elif echo "$model_full" | grep -qi "opus"; then
model_short="Opus"
else
model_short="$model_full"
fi
[ -n "$version" ] && model_short="$model_short $version"
fi
# Poziom rozumowania (brak, gdy model go nie obsługuje)
effort=$(echo "$input" | jq -r '.effort.level // empty')
# Kontekst
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
ctx=""
if [ -n "$used_pct" ]; then
pct_int=$(printf '%.0f' "$used_pct")
c=$(ctx_color "$pct_int")
ctx="${c}⛁ ${pct_int}%${RESET}"
fi
now=$(date +%s)
# Segment limitu: limit_segment <etykieta> <used_pct> <resets_at> <okno_w_sekundach>
limit_segment() {
local label=$1 pct=$2 reset=$3 window=$4
[ -z "$pct" ] && return
local used
used=$(printf '%.0f' "$pct")
local elapsed=-1 timer=""
if [ -n "$reset" ] && [ "$reset" != "null" ]; then
local left=$(( reset - now ))
elapsed=$(( (window - left) * 100 / window ))
[ "$elapsed" -lt 0 ] && elapsed=0
[ "$elapsed" -gt 100 ] && elapsed=100
timer=" ${DIM}$(format_remaining "$left")${RESET}"
fi
local c
if [ "$elapsed" -ge 0 ]; then
c=$(pace_color "$used" "$elapsed")
else
c=$(pct_color "$used")
fi
printf "%s" "${c}${label}${RESET} $(bar "$used" "$elapsed" "$c") ${c}${used}%${RESET}${timer}"
}
five=$(limit_segment "5h" \
"$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')" \
"$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')" \
18000)
week=$(limit_segment "7d" \
"$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')" \
"$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')" \
604800)
# Cache promptu: ◷ i minuty do wygaśnięcia albo ☠☠ gdy zimny
cache=""
cache_warm=$(echo "$input" | jq -r 'if .prompt_cache.warm == null then empty else .prompt_cache.warm end')
cache_exp=$(echo "$input" | jq -r '.prompt_cache.expires_at // empty')
if [ -n "$cache_warm" ]; then
if [ "$cache_warm" = "true" ] && [ -n "$cache_exp" ] && [ "$cache_exp" -gt "$now" ]; then
mins=$(( (cache_exp - now) / 60 ))
if [ "$mins" -le 10 ]; then cc=$RED
elif [ "$mins" -le 30 ]; then cc=$YELLOW
else cc=$GREEN; fi
cache="${cc}◷ ${mins}m${RESET}"
else
cache="${RED}☠☠${RESET}"
fi
fi
# Skraca liczbę: 1234 → 1.2k, 102208 → 102k
short_num() {
local n=$1
if [ "$n" -ge 10000 ]; then
echo "$(( n / 1000 ))k"
elif [ "$n" -ge 1000 ]; then
echo "$(( n / 1000 )).$(( n % 1000 / 100 ))k"
else
echo "$n"
fi
}
# Niezacommitowane linie w repo: +dodane -usunięte
git_diff=""
if [ -n "$dir" ] && git -C "$dir" rev-parse --git-dir >/dev/null 2>&1; then
stat=$(git -C "$dir" diff HEAD --shortstat 2>/dev/null)
ins=$(echo "$stat" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+')
del=$(echo "$stat" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+')
[ -n "$ins" ] && git_diff="${GREEN}+$(short_num "$ins")${RESET}"
[ -n "$del" ] && git_diff="${git_diff:+$git_diff }${RED}-$(short_num "$del")${RESET}"
fi
# Buduj output
SEP=" ${DIM}·${RESET} "
out=""
[ -n "$project" ] && out="${DIM}${project}${RESET}"
[ -n "$model_short" ] && out="$out ${CYAN}${model_short}${RESET}"
[ -n "$effort" ] && out="$out ${DIM}${effort}${RESET}"
[ -n "$cache" ] && out="$out ${DIM}│${RESET} $cache"
[ -n "$ctx" ] && out="$out ${DIM}│${RESET} $ctx"
[ -n "$five" ] && out="$out${SEP}$five"
[ -n "$week" ] && out="$out${SEP}$week"
[ -n "$git_diff" ] && out="$out ${DIM}│${RESET} $git_diff"
printf "%b\n" "$out"Typowe pułapki
- Limity 5h i 7d widzą tylko subskrybenci Pro i Max. Na kluczu API tej części paska nie będzie, reszta działa.
- Limity pojawiają się po pierwszej odpowiedzi w sesji. Świeżo otwarta sesja pokazuje sam model i kontekst.
- Ikony to zwykłe znaki Unicode, bez specjalnej czcionki. Jeśli twój terminal pokaże
⛁jako kolorową emoji albo kwadrat, podmień go w skrypcie na◔. - Git dokłada ułamek sekundy. W moim vaulcie Obsidiana
git difftrwa około 0,6 sekundy. Poza repozytorium ta część po prostu znika. - Kreska skacze co około 8%, bo pasek ma 12 znaków. Kolor liczę z dokładnych procentów, nie z pozycji kreski.
Podsumowanie
- procent limitu bez czasu to połowa informacji, kreska upływu okna dokłada drugą połowę,
- kolor mówi, co zrobić: zielony to gaz, żółty to tempo, czerwony to hamulec,
◷przypomina, że cache zaraz wygaśnie, a☠☠, że już wygasł,- całość to jeden skrypt w bashu i trzy linijki w ustawieniach.
P.S. Poprzednia wersja mojego paska pokazywała same liczby i osobno dwa czasy resetu, bez podpisu, który jest od czego. Przebudowa zajęła mniej czasu niż zgadywanie, co znaczy „2d14h”.
Damian Ślimak. Twój Nawigator w chaosie AI.