20. März 2026
Warum eine eigene Statusbar?
Claude Code zeigt standardmaessig nur wenige Informationen in der Statuszeile an. Mit einem einfachen Bash-Script laesst sich das deutlich erweitern: Modell, Git-Branch mit Staged/Unstaged-Zaehler, Context-Window-Auslastung als Fortschrittsbalken, Session-Kosten und Dauer – alles auf einen Blick.
Das Ergebnis sieht so aus:
[Claude Sonnet 4.6] mein-projekt | main +2 ~1
████████████░░░░░░░░ 60% | $0.42 | 3m 12s
Voraussetzungen
- Claude Code installiert
- jq (JSON-Parser):
brew install jq - Ein Terminal mit ANSI-Farbunterstuetzung (iTerm2, WezTerm, Ghostty, etc.)
Anzeige-Elemente
| Element | Bedeutung |
|---|---|
[Claude Sonnet 4.6] | Aktuell verwendetes Modell |
mein-projekt | Verzeichnisname (klickbarer Link zum Repo) |
main | Git-Branch (klickbarer Link zum Branch) |
+2 | Anzahl staged Aenderungen (gruen) |
~1 | Anzahl unstaged Aenderungen (gelb) |
| Fortschrittsbalken | Context-Window-Auslastung |
60% | Context-Window-Nutzung in Prozent |
$0.42 | Gesamtkosten der Session |
3m 12s | Bisherige Sessiondauer |
Farben des Context-Balkens
| Farbe | Bereich | Bedeutung |
|---|---|---|
| Gruen | 0 – 69% | Alles gut |
| Gelb | 70 – 89% | Bald neue Session starten |
| Rot | ab 90% | Context fast voll |
Installation
1. Script anlegen
Die Datei ~/.claude/statusline.sh mit folgendem Inhalt erstellen:
#!/bin/bash
# Claude Code status line - two lines: git info + context/cost
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'
# Git info with caching (refresh every 5s)
CACHE_FILE="/tmp/claude-statusline-git-cache"
CACHE_MAX_AGE=5
cache_is_stale() {
[ ! -f "$CACHE_FILE" ] || \
[ $(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0))) -gt $CACHE_MAX_AGE ]
}
BRANCH=""
GIT_STATUS=""
REMOTE_URL=""
if cache_is_stale; then
if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
STAGED=$(git diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
MODIFIED=$(git diff --numstat 2>/dev/null | wc -l | tr -d ' ')
REMOTE=$(git remote get-url origin 2>/dev/null \
| sed 's/git@github\.com:/https:\/\/github.com\//' \
| sed 's/\.git$//')
echo "$BRANCH|$STAGED|$MODIFIED|$REMOTE" > "$CACHE_FILE"
else
echo "|||" > "$CACHE_FILE"
fi
fi
IFS='|' read -r BRANCH STAGED MODIFIED REMOTE_URL < "$CACHE_FILE"
if [ -n "$BRANCH" ]; then
[ "$STAGED" -gt 0 ] && GIT_STATUS="${GREEN}+${STAGED}${RESET}"
[ "$MODIFIED" -gt 0 ] && GIT_STATUS="${GIT_STATUS} ${YELLOW}~${MODIFIED}${RESET}"
if [ -n "$REMOTE_URL" ]; then
BRANCH_LINK="\e]8;;${REMOTE_URL}/tree/${BRANCH}\a${BRANCH}\e]8;;\a"
else
BRANCH_LINK="${BRANCH}"
fi
GIT_INFO=" | ${BRANCH_LINK} ${GIT_STATUS}"
else
GIT_INFO=""
fi
# Line 1: model, directory (clickable repo link), git branch
DIR_NAME="${DIR##*/}"
if [ -n "$REMOTE_URL" ]; then
DIR_LINK="\e]8;;${REMOTE_URL}\a${DIR_NAME}\e]8;;\a"
else
DIR_LINK="${DIR_NAME}"
fi
printf '%b\n' "${CYAN}[${MODEL}]${RESET} ${DIR_LINK}${GIT_INFO}"
# Line 2: context bar + cost + duration
if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
else BAR_COLOR="$GREEN"; fi
FILLED=$((PCT / 5)); EMPTY=$((20 - FILLED))
BAR=""
[ "$FILLED" -gt 0 ] && BAR=$(printf "%${FILLED}s" | tr ' ' '█')
[ "$EMPTY" -gt 0 ] && BAR="${BAR}$(printf "%${EMPTY}s" | tr ' ' '░')"
COST_FMT=$(printf '$%.2f' "$COST")
MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))
echo -e "${BAR_COLOR}${BAR}${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ${MINS}m ${SECS}s"
2. Script ausfuehrbar machen
chmod +x ~/.claude/statusline.sh
3. settings.json anpassen
Die Datei ~/.claude/settings.json oeffnen und das statusLine-Objekt ergaenzen:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}
4. Claude Code neu starten
Nach dem Neustart erscheint die neue Statusbar am unteren Rand des Terminals.
Wie das Script funktioniert
Claude Code uebergibt bei jedem Statuszeilen-Update ein JSON-Objekt per stdin an das konfigurierte Script. Darin enthalten sind unter anderem:
model.display_name– das aktive Modellworkspace.current_dir– das aktuelle Arbeitsverzeichniscost.total_cost_usd– die bisherigen Session-Kostencontext_window.used_percentage– die Context-Auslastungcost.total_duration_ms– die Sessiondauer in Millisekunden
Das Script parst diese Werte mit jq und baut daraus zwei Zeilen zusammen.
Git-Caching
Da die Statuszeile haeufig aktualisiert wird, cached das Script die Git-Informationen in /tmp/claude-statusline-git-cache. Der Cache wird alle 5 Sekunden erneuert. So bleibt die Anzeige responsiv, ohne dass bei jedem Update git-Befehle ausgefuehrt werden muessen.
Klickbare Links
In Terminals mit OSC 8-Unterstuetzung (iTerm2, WezTerm, Ghostty) werden sowohl der Verzeichnisname als auch der Branch-Name als klickbare Links dargestellt, die direkt zum Repository bzw. Branch auf GitHub fuehren.
Windows-Variante
Unter Windows laesst sich dasselbe mit einem PowerShell-Script umsetzen. Statt jq kommt das eingebaute ConvertFrom-Json zum Einsatz. Die settings.json sieht dann so aus:
{
"statusLine": {
"type": "command",
"command": "powershell -NoProfile -NonInteractive -File ~/.claude/statusline.ps1"
}
}
Hinweise
- Kein Git-Repo: Ausserhalb eines Repositories werden nur Modell und Verzeichnis angezeigt.
- Terminal-Kompatibilitaet: Aeltere Terminals (z.B. macOS Terminal.app) zeigen die OSC-8-Links als reinen Text an.
- Enterprise GitHub: Das Script kann SSH-URLs automatisch in HTTPS-Links umwandeln – dafuer den
sed-Befehl im Script an die eigene Domain anpassen.