Premessa
Quando si lavora a lungo con Claude Code dal terminale, due informazioni contano più di tutte: quale modello sta rispondendo e quanto spazio resta nella finestra di contesto. Di default la riga di stato del terminale non lo dice, così è facile arrivare a contesto quasi pieno senza accorgersene. La soluzione è una status line personalizzata: una sola riga, sempre visibile in fondo alla sessione, che mostra il modello attivo e una barra colorata con la percentuale di contesto consumato e i token usati.
In questo articolo racconto come l’ho realizzata. Il mio ambiente di lavoro è Windows, quindi lo script vero e proprio è in PowerShell, ma il meccanismo è identico su Linux e in fondo trovi la versione bash pronta da incollare.
Cosa mostra la status line
Il risultato è una riga compatta divisa in tre parti, separate da una barra verticale:
- Il modello, scritto in ciano, per sapere a colpo d’occhio se sto usando Opus, Sonnet o altro.
- Una barra di avanzamento di venti caratteri, che si riempie man mano che il contesto si consuma e cambia colore in base a quanto è pieno.
- I numeri: la percentuale di contesto usata e i token in ingresso rispetto alla dimensione totale della finestra (per esempio 45000 su 200k).
La barra usa il carattere pieno per la parte consumata e quello tratteggiato per la parte ancora libera. Il colore segue tre soglie: verde finché il contesto è sotto la metà, giallo tra il 50 e il 79 per cento, rosso dall’80 per cento in su. In questo modo basta uno sguardo periferico per capire se conviene chiudere o riassumere la sessione.

Come Claude Code alimenta la status line
Il funzionamento è semplice e si presta bene a qualunque linguaggio. Nelle impostazioni si dichiara un comando di tipo “command”: a ogni aggiornamento della riga di stato, Claude Code esegue quel comando e gli passa sullo standard input un oggetto JSON con i dati della sessione. Lo script deve solo leggere quel JSON, comporre una stringa e stamparla. Tutto quello che finisce nello standard output diventa la status line.
I campi che servono a questo scopo sono quattro:
model.display_name: il nome leggibile del modello.context_window.used_percentage: la percentuale di contesto già occupata.context_window.context_window_size: la dimensione totale della finestra di contesto.context_window.total_input_tokens: i token in ingresso accumulati nella sessione.
I colori si ottengono con le classiche sequenze di escape ANSI, quelle che il terminale interpreta come istruzioni di formattazione invece di stamparle come testo.
La versione Windows in PowerShell
Su Windows ho scelto PowerShell perché è già presente nel sistema e legge il JSON senza dipendenze esterne. Lo script raccoglie tutto lo standard input, lo converte in oggetto, estrae i quattro campi e costruisce la riga. Il cuore grafico è il calcolo della barra: venti caratteri totali, la quota piena proporzionale alla percentuale, il colore scelto sulle tre soglie.
$d = $input | Out-String
if (-not $d.Trim()) { exit 0 }
try { $j = $d | ConvertFrom-Json } catch { exit 0 }
$m = if ($j.model.display_name) { $j.model.display_name } else { 'Unknown' }
$p = $j.context_window.used_percentage
$t = $j.context_window.context_window_size
$u = $j.context_window.total_input_tokens
$esc = [char]27
$c = "${esc}[1;36m" # ciano (modello)
$y = "${esc}[1;33m" # giallo (percentuale)
$g = "${esc}[1;32m" # verde (token)
$di = "${esc}[2m" # attenuato (parte vuota della barra)
$r = "${esc}[0m" # reset
if ($null -ne $p -and $null -ne $t -and $null -ne $u) {
$pf = [math]::Round($p, 0)
$tk = if ($t -ge 1000) { "$([math]::Round($t / 1000, 0))k" } else { "$t" }
$bars = 20
$filled = [math]::Round($bars * $p / 100)
$empty = $bars - $filled
$barColor = if ($pf -ge 80) { "${esc}[1;31m" } elseif ($pf -ge 50) { "${esc}[1;33m" } else { "${esc}[1;32m" }
$bar = "${barColor}$([string][char]0x2588 * $filled)${di}$([string][char]0x2591 * $empty)${r}"
[Console]::Write("${c}${m}${r} | [${bar}] ${y}${pf}%${r} | ${g}${u} / ${tk}${r}")
} else {
[Console]::Write("${c}${m}${r} | ${di}No token data yet${r}")
}Due dettagli meritano una nota. Il carattere pieno della barra è il blocco Unicode 0x2588 e quello vuoto è il tratteggio 0x2591: moltiplicandoli per il numero di posizioni si ottiene la barra senza cicli espliciti. La dimensione della finestra viene compattata dividendo per mille e aggiungendo la lettera k, così invece di 200000 si legge 200k. Se per qualche motivo i dati sul contesto non sono ancora disponibili, lo script ripiega su un messaggio neutro con il solo nome del modello.
Per registrarlo basta indicare il comando nel file di configurazione di Claude Code, di solito settings.json nella cartella .claude dell’utente. Su Windows il comando invoca PowerShell senza profilo, in modo non interattivo, puntando allo script:
{
"statusLine": {
"type": "command",
"command": "powershell -NoProfile -NonInteractive -File "C:/Users/tuonome/.claude/statusline.ps1""
}
}La versione Linux in bash
Su Linux la logica non cambia di una virgola: cambia solo lo strumento per leggere il JSON. Al posto del comando nativo di PowerShell si usa jq, il classico processore JSON da riga di comando, che quasi tutte le distribuzioni offrono nei repository. Se non è installato lo si aggiunge con il gestore di pacchetti, per esempio sudo apt install jq su Debian e Ubuntu, oppure sudo dnf install jq su Fedora.
Lo script bash legge lo standard input, estrae i quattro campi con jq, calcola la barra e stampa la riga con le stesse sequenze ANSI e le stesse tre soglie di colore. Il carattere pieno e quello tratteggiato sono scritti direttamente come simboli Unicode, dato che il terminale Linux li gestisce nativamente.
#!/usr/bin/env bash
# ~/.claude/statusline.sh
input=$(cat)
[ -z "$(printf '%s' "$input" | tr -d '[:space:]')" ] && exit 0
model=$(printf '%s' "$input" | jq -r '.model.display_name // "Unknown"')
p=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')
t=$(printf '%s' "$input" | jq -r '.context_window.context_window_size // empty')
u=$(printf '%s' "$input" | jq -r '.context_window.total_input_tokens // empty')
esc=$'33'
c="${esc}[1;36m" # ciano (modello)
y="${esc}[1;33m" # giallo (percentuale)
g="${esc}[1;32m" # verde (token)
di="${esc}[2m" # attenuato (parte vuota della barra)
r="${esc}[0m" # reset
if [ -n "$p" ] && [ -n "$t" ] && [ -n "$u" ]; then
pf=$(printf '%.0f' "$p")
if [ "$t" -ge 1000 ]; then tk="$(( (t + 500) / 1000 ))k"; else tk="$t"; fi
bars=20
filled=$(awk -v b="$bars" -v p="$p" 'BEGIN{printf "%d", (b*p/100)+0.5}')
empty=$(( bars - filled ))
if [ "$pf" -ge 80 ]; then bar_color="${esc}[1;31m"
elif [ "$pf" -ge 50 ]; then bar_color="${esc}[1;33m"
else bar_color="${esc}[1;32m"; fi
fill=""; for ((i=0; i<filled; i++)); do fill+="█"; done
rest=""; for ((i=0; i<empty; i++)); do rest+="░"; done
bar="${bar_color}${fill}${di}${rest}${r}"
printf '%b%s%b | [%b] %b%s%%%b | %b%s / %s%b' "$c" "$model" "$r" "$bar" "$y" "$pf" "$r" "$g" "$u" "$tk" "$r"
else
printf '%b%s%b | %bNo token data yet%b' "$c" "$model" "$r" "$di" "$r"
fiDopo aver salvato il file conviene renderlo eseguibile con chmod +x ~/.claude/statusline.sh. La registrazione nel settings.json è ancora più diretta che su Windows, perché basta richiamare bash sullo script:
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline.sh"
}
}Un paio di accortezze specifiche di bash. La percentuale arriva come numero con decimali, quindi per arrotondarla al numero intero più vicino mi appoggio ad awk, che gestisce la matematica in virgola mobile meglio dell’aritmetica intera della shell. La barra viene composta con due piccoli cicli, uno per le posizioni piene e uno per quelle vuote, perché bash non ha la moltiplicazione di stringhe di PowerShell. Il risultato a video, però, è identico.
Perché funziona uguale ovunque
Il punto interessante è che Claude Code non impone né un linguaggio né un formato di uscita: chiede solo un comando che riceva il JSON e restituisca testo. Questo rende la status line completamente portabile. La parte grafica, cioè barra, soglie e colori ANSI, vive nella stringa finale ed è la stessa identica su Windows e su Linux. Cambia soltanto il modo di leggere il JSON e di ripetere un carattere, dettagli che ogni shell risolve a modo suo.
Da quando ho questa riga sotto agli occhi non mi capita più di sforare il contesto senza accorgermene: la barra passa al giallo e poi al rosso con largo anticipo, e so sempre quale modello sto facendo lavorare. È una di quelle micro personalizzazioni che costano dieci minuti e si ripagano a ogni sessione.
Per maggiori informazioni contattami: info@davidemugnaini.it.