Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Enhancement: Add account usage limits to statusline (session %, 7-day %, Sonnet %)

Aperta
#32 1 commento 3 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
shell
Ambito
cli, tooling

Direzione di ricerca

Inizia da scripts/statusline.sh e traccia come vengono assemblate le righe esistenti di contesto, costo e durata. Esamina i percorsi proposti per credentials, cache, curl, jq e reset-formatting, quindi esegui la statusline con e senza credentials e con un’API non disponibile. Il lavoro è completo quando l’utilizzo dell’account viene visualizzato quando disponibile, mentre credentials mancanti, errori, dati Sonnet null e jq mancante preservano le righe esistenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

The current scripts/statusline.sh shows context window usage, cost, and session duration. This proposal adds a third line displaying account-level rate limit usage — session (5-hour), weekly (all models), and weekly (Sonnet-only) — fetched from Anthropic's OAuth usage API with local caching.

Problem

Heavy Claude Code users frequently hit the 5-hour session limit or weekly limits without any visible warning until they get a hard block. The existing statusline has no visibility into these limits.

Proposed Solution

Add a Line 3 to the statusline that shows account usage limits in real time:

[Sonnet 4.6] 📁 my-project │ 🌿 main

████████░░░░ 42% (84k/200k) │ $0.00 │ ⏱ 12m 30s │ ↻78%

Session: 42% ⟳2h18m │ 7d all: 15% ⟳Sat 16h │ Sonnet: 18% ⟳Sat 16h

Color-coded with the same thresholds as the existing context bar:

  • 🟢 Green: < 50%
  • 🟡 Yellow: 50–79%
  • 🔴 Red: ≥ 80%

API

The data comes from an undocumented but stable Anthropic OAuth endpoint:

GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <oauth-access-token>
anthropic-version: 2023-06-01
anthropic-beta: oauth-2025-04-20

Response:

{
  "five_hour": {
    "utilization": 42.0,
    "resets_at": "2026-02-22T00:00:00.318160+00:00"
  },
  "seven_day": {
    "utilization": 15.0,
    "resets_at": "2026-02-28T19:00:00.318184+00:00"
  },
  "seven_day_sonnet": {
    "utilization": 18.0,
    "resets_at": "2026-02-28T19:00:00.318198+00:00"
  },
  "seven_day_opus": null,
  "extra_usage": {
    "is_enabled": false,
    "monthly_limit": null
  }
}

The token is read directly from ~/.claude/.credentials.json (the same file Claude Code already uses), so no additional configuration is needed.

Implementation Details

Caching strategy

The statusline runs on every Claude Code render cycle. To avoid hammering the API, usage data is cached in ~/.claude/usage-cache.json with a 2-minute TTL:

USAGE_CACHE="$HOME/.claude/usage-cache.json"
CACHE_TTL=120

fetch_usage() {
    local now
    now=$(date +%s)

    if [[ -f "$USAGE_CACHE" ]]; then
        local cache_time
        cache_time=$(jq -r '.cached_at // 0' "$USAGE_CACHE" 2>/dev/null)
        if [[ $((now - cache_time)) -lt $CACHE_TTL ]]; then
            cat "$USAGE_CACHE"
            return
        fi
    fi

    local token
    token=$(jq -r '.claudeAiOauth.accessToken // empty' \
        "$HOME/.claude/.credentials.json" 2>/dev/null)
    [[ -z "$token" ]] && { [[ -f "$USAGE_CACHE" ]] && cat "$USAGE_CACHE" || echo "{}"; return; }

    local response
    response=$(curl -sf --max-time 4 \
        -H "Authorization: Bearer $token" \
        -H "Content-Type: application/json" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: oauth-2025-04-20" \
        "https://api.anthropic.com/api/oauth/usage" 2>/dev/null)

    if [[ -n "$response" ]] && echo "$response" | jq -e '.five_hour' &>/dev/null; then
        echo "$response" | jq ". + {cached_at: $now}" > "$USAGE_CACHE" 2>/dev/null
        echo "$response"
    else
        # Serve stale cache on failure rather than breaking the statusline
        [[ -f "$USAGE_CACHE" ]] && cat "$USAGE_CACHE" || echo "{}"
    fi
}
Reset time formatting
format_reset() {
    local iso="$1"
    [[ -z "$iso" || "$iso" == "null" ]] && echo "?" && return

    local reset_epoch now_epoch diff
    reset_epoch=$(date -d "$iso" +%s 2>/dev/null) || { echo "?"; return; }
    now_epoch=$(date +%s)
    diff=$(( reset_epoch - now_epoch ))

    if [[ $diff -le 0 ]]; then
        echo "now"
    elif [[ $diff -lt 3600 ]]; then
        printf "%dm" $(( diff / 60 ))
    elif [[ $diff -lt 86400 ]]; then
        printf "%dh%dm" $(( diff / 3600 )) $(( (diff % 3600) / 60 ))
    else
        LC_TIME=C date -d "$iso" +"%a %Hh" 2>/dev/null || echo "?"
    fi
}
Line 3 assembly
if [ -n "$sess_pct" ] && [ "$sess_pct" != "null" ]; then
    if   [ "$sess_pct" -lt 50 ]; then sess_color='\033[32m'
    elif [ "$sess_pct" -lt 80 ]; then sess_color='\033[33m'
    else                               sess_color='\033[31m'; fi

    sess_reset=$(format_reset "$sess_reset_at")
    line3="$(printf '\033[2mSession:\033[0m %b%s%%\033[0m \033[2m⟳%s\033[0m' \
        "$sess_color" "$sess_pct" "$sess_reset")"

    # 7-day all models
    if [ -n "$week_pct" ] && [ "$week_pct" != "null" ]; then
        if   [ "$week_pct" -lt 50 ]; then week_color='\033[32m'
        elif [ "$week_pct" -lt 80 ]; then week_color='\033[33m'
        else                               week_color='\033[31m'; fi

        week_reset=$(format_reset "$week_reset_at")
        line3="$line3 $(printf '%b \033[2m7d all:\033[0m %b%s%%\033[0m \033[2m⟳%s\033[0m' \
            "$SEP" "$week_color" "$week_pct" "$week_reset")"
    fi

    # 7-day Sonnet-only (only shown when non-null)
    if [ -n "$sonnet_pct" ] && [ "$sonnet_pct" != "null" ]; then
        if   [ "$sonnet_pct" -lt 50 ]; then son_color='\033[32m'
        elif [ "$sonnet_pct" -lt 80 ]; then son_color='\033[33m'
        else                                 son_color='\033[31m'; fi

        line3="$line3 $(printf '%b \033[2mSonnet:\033[0m %b%s%%\033[0m \033[2m⟳%s\033[0m' \
            "$SEP" "$son_color" "$sonnet_pct" "$(format_reset "$sonnet_reset_at")")"
    fi
fi

Failure modes

Scenario Behavior
No credentials file Line 3 omitted entirely, Lines 1–2 unaffected
API unreachable / timeout (4s max) Serves stale cache; if no cache, Line 3 omitted
API returns error JSON Stale cache used; graceful fallback to no Line 3
seven_day_sonnet is null (Opus plan) Sonnet segment omitted from Line 3
jq not installed No Line 3; existing behavior preserved

Token count display (bonus)

While at it, Line 2 also gains an absolute token count display — useful alongside the percentage for planning context compaction:

████████░░░░ 42% (84k/200k) │ $0.00 │ ⏱ 12m 30s

Related

Happy to submit a PR if this direction makes sense to the maintainers.

Lingua principale
Shell
Stelle
2.1k
Fork
162
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di trailofbits/claude-code-config

Tutte le issue di trailofbits/claude-code-config

Issue simili

Altre issue su Shell/Bash

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.