dotfiles bugabingas dorkfiles
owned by admin
README Source History Refs Compare Notes Search Rendered preview Claude Code Statusline
Eine einzeilige, Statusline für Claude Code.
Reines Node (stdlib), ein Renderer + ein Hook. Cross-Plattform (win/mac/linux).
Beispielausgabe:
RD-1950 · Opus 4.8 · xhigh · RD-1950 · 5h ██▋░░░░░ 33%·2h44m · 7d █▏░░░░░░ 14% · 🔥$26.68/hr · $0.499 $136.54Σ $486.13☾ · caveman:full
Segmente (v.l.n.r.): Verzeichnis · Modell · Effort · Git/JJ-Branch · 5h-Limit ·
7d-Limit · Burn-Rate ($/h) · Kosten (Turn / Session Σ / Monat ☾) · Caveman-Badge.
Voraussetzungen
Dep
Pflicht
Zweck
Node ≥ 18
✅
Laufzeit. Nur stdlib (fs/os/path/crypto/child_process), keine npm-Pakete.
Claude Code
✅
Liefert den JSON-Payload (inkl. Kosten) via stdin.
git oder jj
➖
Branch-Segment. Muss im PATH sein. Ohne → Segment entfällt.
Nerd Font
➖ (empfohlen)
Glyphen ``, Balken █▏░, Icons. Ohne → Tofu (`□`).
caveman-Plugin
➖
Caveman-Badge. Ohne → Badge entfällt.
Dateien
Beide nach ~/.claude/ kopieren oder symlinken:
ln -s "$PWD/statusline.js" ~/.claude/statusline.js
ln -s "$PWD/cc-statusline-hook.js" ~/.claude/cc-statusline-hook.js
Installation
Node ≥ 18 installieren, im PATH.
Beide Dateien nach ~/.claude/ (s.o.).
~/.claude/settings.json ergänzen (Auszug unten).
Nerd Font im Terminal aktivieren (sonst Tofu statt Glyphen).
Claude Code neu starten.
settings.json (Auszug)
{
"statusLine": {
"type": "command",
"command": "node ~/.claude/statusline.js"
},
"hooks": {
// Turn-Marker: Basis für die "Turn"-Kosten (Δ seit letztem Prompt)
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "node ~/.claude/cc-statusline-hook.js" }
]
}
],
// Workflow-Badge: NUR beim Workflow-Tool feuern (matcher scoped!)
"PreToolUse": [
{
"matcher": "Workflow",
"hooks": [
{ "type": "command", "command": "node ~/.claude/cc-statusline-hook.js" }
]
}
]
}
}
Der Hook ist ein Skript für beide Events; es verzweigt über hook_event_name.
Funktionsweise
Claude Code spawnt statusline.js pro Render (frischer Prozess, Payload via
stdin, 300 ms Debounce, event-getriggert: neue Assistant-Nachricht, /compact,
Permission-/Vim-Mode-Wechsel). Per-Render-Spawn ist von der API erzwungen.
Renderer baut Segmente, jeweils eigener try/catch (ein Crash darf die Zeile nicht
leeren), und schreibt ohne Trailing-Newline.
Turn-Kosten : Der Hook legt bei UserPromptSubmit eine Marker-Datei
~/.claude/.cc-turn-<session> an. Der nächste Render liest sie, rebaselined den
Turn-Start und löscht den Marker.
Workflow-Badge : Bei PreToolUse(Workflow) schreibt der Hook eine selbst-
ablaufende Zeile nach ~/.claude/.cc-statusline-extra (TTL 120 s), die der Renderer
rendert.
Kosten-Ledger ~/.claude/.cc-cost-ledger.json: Turn / Session / Monat (monats-
übergreifend kumuliert). Idle-Renders (keine Kostenänderung) schreiben nicht.
Selbst-GC räumt alte .cc-*.tmp / .cc-turn-* (> 1 Tag) auf.
Anpassung
Tunables stehen oben in statusline.js im CONFIG-Block:
Schlüssel
Default
Bedeutung
sep
" · "
Trenner zwischen Segmenten.
barWidth
8
Zellen pro Usage-Balken.
costStyle
"icon"
"icon" = helle $Zahl + gedämpftes Glyph; "slash" = $x/turn.
gitCacheTtlMs
8000
Cache für git status (Spawn ist ~400 ms kalt auf win32).
contextWarnPct/CritPct
70/90
Schwellen Kontext-Balken (gelb/rot).
usageWarnPct/CritPct
50/80
Schwellen Rate-Limit-Balken.
burnWindowMs
10 min
Fenster für die Burn-Rate ($/h).
Performance (win32)
Harte Untergrenze ist nicht das Skript, sondern der Node-Kaltstart:
node -e 0 ≈ 120 ms (Prozess-Spawn + V8-Init). Nicht durch Flags reduzierbar.
< 100 ms ist mit Node unmöglich. Nur ein kompiliertes Binary (Go/Rust ~10–20 ms)
unterbietet das — kostet aber Cross-Plattform (per-OS-Builds) + zweite Codebase.
Bun (win32) und Deno sind langsamer als Node; LLRT kann kein stdin lesen. → Node.
Die Bar ist asynchron und blockiert keine Eingabe; ~120–140 ms sind unsichtbar.
Troubleshooting
Symptom
Ursache / Fix
□/Tofu statt Glyphen
Nerd Font nicht aktiv im Terminal.
Keine Kosten
Alte Claude-Code-Version ohne cost im Payload.
Kein Branch-Segment
git/jj nicht im PATH, oder nicht in einem Repo.
Keine Turn-Kosten
Hook nicht in UserPromptSubmit registriert.
Statusline leer
statusline.js wirft beim Start — manuell testen: echo '{}' | node ~/.claude/statusline.js.
# Claude Code Statusline
Eine einzeilige, Statusline für Claude Code.
Reines Node (stdlib), ein Renderer + ein Hook. Cross-Plattform (win/mac/linux).
Beispielausgabe:
```
RD-1950 · Opus 4.8 · xhigh · RD-1950 · 5h ██▋░░░░░ 33%·2h44m · 7d █▏░░░░░░ 14% · 🔥$26.68/hr · $0.499 $136.54Σ $486.13☾ · caveman:full
```
Segmente (v.l.n.r.): Verzeichnis · Modell · Effort · Git/JJ-Branch · 5h-Limit ·
7d-Limit · Burn-Rate ($/h) · Kosten (Turn / Session Σ / Monat ☾) · Caveman-Badge.
---
## Voraussetzungen
| Dep | Pflicht | Zweck |
|-----|---------|-------|
| **Node ≥ 18** | ✅ | Laufzeit. Nur stdlib ( `fs/os/path/crypto/child_process` ), keine npm-Pakete. |
| **Claude Code** | ✅ | Liefert den JSON-Payload (inkl. Kosten) via stdin. |
| **git** oder **jj** | ➖ | Branch-Segment. Muss im `PATH` sein. Ohne → Segment entfällt. |
| **Nerd Font** | ➖ (empfohlen) | Glyphen ``, Balken `█▏░` , Icons. Ohne → Tofu ( `□` ). |
| **caveman-Plugin** | ➖ | Caveman-Badge. Ohne → Badge entfällt. |
---
## Dateien
| Datei | Rolle |
|-------|-------|
| [ `statusline.js` ](./statusline.js) | Renderer. Liest stdin-JSON, gibt eine Zeile aus. |
| [ `cc-statusline-hook.js` ](./cc-statusline-hook.js) | Hook. Setzt Turn-Marker + Workflow-Badge. |
Beide nach `~/.claude/` kopieren oder symlinken:
``` bash
ln -s "$PWD/statusline.js" ~/.claude/statusline.js
ln -s "$PWD/cc-statusline-hook.js" ~/.claude/cc-statusline-hook.js
```
---
## Installation
1. Node ≥ 18 installieren, im `PATH` .
2. Beide Dateien nach `~/.claude/` (s.o.).
3. `~/.claude/settings.json` ergänzen (Auszug unten).
4. Nerd Font im Terminal aktivieren (sonst Tofu statt Glyphen).
5. Claude Code neu starten.
### settings.json (Auszug)
``` jsonc
{
"statusLine": {
"type": "command",
"command": "node ~/.claude/statusline.js"
},
"hooks": {
// Turn-Marker: Basis für die "Turn"-Kosten (Δ seit letztem Prompt)
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "node ~/.claude/cc-statusline-hook.js" }
]
}
],
// Workflow-Badge: NUR beim Workflow-Tool feuern (matcher scoped!)
"PreToolUse": [
{
"matcher": "Workflow",
"hooks": [
{ "type": "command", "command": "node ~/.claude/cc-statusline-hook.js" }
]
}
]
}
}
```
Der Hook ist **ein** Skript für beide Events; es verzweigt über `hook_event_name` .
---
## Funktionsweise
- Claude Code spawnt `statusline.js` **pro Render** (frischer Prozess, Payload via
stdin, 300 ms Debounce, event-getriggert: neue Assistant-Nachricht, `/compact` ,
Permission-/Vim-Mode-Wechsel). Per-Render-Spawn ist von der API erzwungen.
- Renderer baut Segmente, jeweils eigener `try/catch` (ein Crash darf die Zeile nicht
leeren), und schreibt **ohne** Trailing-Newline.
- **Turn-Kosten** : Der Hook legt bei `UserPromptSubmit` eine Marker-Datei
`~/.claude/.cc-turn-<session>` an. Der nächste Render liest sie, rebaselined den
Turn-Start und löscht den Marker.
- **Workflow-Badge** : Bei `PreToolUse(Workflow)` schreibt der Hook eine selbst-
ablaufende Zeile nach `~/.claude/.cc-statusline-extra` (TTL 120 s), die der Renderer
rendert.
- **Kosten-Ledger** `~/.claude/.cc-cost-ledger.json` : Turn / Session / Monat (monats-
übergreifend kumuliert). Idle-Renders (keine Kostenänderung) schreiben nicht.
Selbst-GC räumt alte `.cc-*.tmp` / `.cc-turn-*` (> 1 Tag) auf.
---
## Anpassung
Tunables stehen oben in `statusline.js` im `CONFIG` -Block:
| Schlüssel | Default | Bedeutung |
|-----------|---------|-----------|
| `sep` | `" · "` | Trenner zwischen Segmenten. |
| `barWidth` | `8` | Zellen pro Usage-Balken. |
| `costStyle` | `"icon"` | `"icon"` = helle `$Zahl` + gedämpftes Glyph; `"slash"` = `$x/turn` . |
| `gitCacheTtlMs` | `8000` | Cache für `git status` (Spawn ist ~400 ms kalt auf win32). |
| `contextWarnPct` / `CritPct` | `70` / `90` | Schwellen Kontext-Balken (gelb/rot). |
| `usageWarnPct` / `CritPct` | `50` / `80` | Schwellen Rate-Limit-Balken. |
| `burnWindowMs` | `10 min` | Fenster für die Burn-Rate ($/h). |
---
## Performance (win32)
- Harte Untergrenze ist **nicht** das Skript, sondern der Node-Kaltstart:
`node -e 0` ≈ **120 ms** (Prozess-Spawn + V8-Init). Nicht durch Flags reduzierbar.
- **< 100 ms ist mit Node unmöglich.** Nur ein kompiliertes Binary (Go/Rust ~10–20 ms)
unterbietet das — kostet aber Cross-Plattform (per-OS-Builds) + zweite Codebase.
Bun (win32) und Deno sind langsamer als Node; LLRT kann kein stdin lesen. → Node.
- Die Bar ist asynchron und blockiert keine Eingabe; ~120–140 ms sind unsichtbar.
---
## Troubleshooting
| Symptom | Ursache / Fix |
|---------|---------------|
| `□` /Tofu statt Glyphen | Nerd Font nicht aktiv im Terminal. |
| Keine Kosten | Alte Claude-Code-Version ohne `cost` im Payload. |
| Kein Branch-Segment | `git` / `jj` nicht im `PATH` , oder nicht in einem Repo. |
| Keine Turn-Kosten | Hook nicht in `UserPromptSubmit` registriert. |
| Statusline leer | `statusline.js` wirft beim Start — manuell testen: `echo '{}' \| node ~/.claude/statusline.js` . |