SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-13

Claude Code statusline instellen op een VPS

Voorkom fouten op servers door een statusregel in Claude Code te configureren. Leer hoe u via settings.json de hostname, git-branch en model direct onder uw prompt toont.

Wat een statusregel van Claude Code weergeeft

Een statusregel van Claude Code is een rij onder de prompt die de uitvoer van een door u geschreven script toont. U voegt een statusLine-blok toe aan settings.json en verwijst dit naar een commando. Claude Code voert dat commando uit, verstuurt de sessiestatus als JSON via standard input naar het script en drukt alles af wat het commando naar standard output schrijft.

Dat is de volledige overeenkomst. Uw script leest JSON via stdin en drukt tekst af naar stdout. Het script draait op uw eigen machine en niets van wat het afdrukt wordt naar het model verzonden, dus het kost geen tokens.

Op een laptop met één project is dit decoratie. Op drie servers is het een veiligheidsmaatregel. Elke Claude Code-sessie ziet er in elke terminal hetzelfde uit, dus vier SSH-vensters zonder labels is de manier waarop een migratie op de verkeerde server terechtkomt. Een statusregel die begint met de hostname beëindigt dat type fout.

Waar de instelling statusLine zich bevindt in settings.json

Plaats deze in uw gebruikersinstellingen op ~/.claude/settings.json, wat van toepassing is op elk project op die machine. Projectinstellingen op .claude/settings.json binnen een repository werken ook, en deze krijgen voorrang voor die map.

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

type is altijd "command". De waarde command wordt uitgevoerd via een shell, dus het kan een scriptpad of een eenvoudig commando zijn. Controleer of de koppeling werkt voordat u een script schrijft:

{
  "statusLine": {
    "type": "command",
    "command": "hostname -s"
  }
}

Start Claude Code en verstuur één bericht. De balk onder de prompt toont nu de korte hostnaam van de server. Als deze leeg blijft, ligt het probleem bij de instelling of het vertrouwensdialoogvenster, niet bij uw script. Lees hieronder "Waarom de statusline leeg blijft".

Sinds augustus 2026 bestaan er drie optionele sleutels. padding voegt horizontale witruimte toe in tekens en is standaard 0. refreshInterval voert het commando elke N seconden opnieuw uit bovenop de normale triggers, met een minimum van 1; dit is alleen gewenst wanneer de regel een klok of iets anders toont dat verandert terwijl de sessie inactief is. hideVimModeIndicator onderdrukt de ingebouwde -- INSERT ---tekst wanneer uw eigen script de vim-modus al rendert.

Welke gegevens ontvangt het statusline-script?

Vertrouw niet op een lijst met velden die u ergens leest, ook niet op deze pagina. Leg het werkelijke object vast dat uw versie verstuurt. Schrijf een tijdelijk script dat stdin opslaat in een bestand:

cat > ~/.claude/statusline-capture.sh <<'EOF'
#!/bin/bash
cat > /tmp/statusline-input.json
echo "captured"
EOF
chmod +x ~/.claude/statusline-capture.sh

Wijs statusLine.command naar dat bestand, start een sessie en verstuur één bericht. De balk leest captured. Bekijk nu wat er is aangekomen:

jq . /tmp/statusline-input.json

U beschikt nu over de exacte structuur voor uw build en u kunt dit herhalen telkens wanneer een update iets wijzigt.

De stabiele onderdelen, zoals gedocumenteerd in augustus 2026, zijn geneste objecten in plaats van platte keys. model bevat id en display_name. workspace bevat current_dir en project_dir: current_dir is waar de sessie zich nu bevindt, project_dir is waar deze werd gestart, en de twee verschillen zodra de werkmap halverwege de sessie wijzigt. De top-level cwd bevat dezelfde waarde als workspace.current_dir. context_window bevat token-aantallen plus een vooraf berekende used_percentage. cost bevat total_cost_usd en duur-tellers. session_id is stabiel gedurende de levensduur van de sessie en uniek per sessie, wat later van belang is voor caching.

Drie regels houden een script in leven bij schemawijzigingen.

Sommige keys zijn afwezig, niet null. vim, agent, pr, worktree en effort verschijnen alleen wanneer de bijbehorende functie actief is. Het uitlezen van .vim.mode met jq -r terwijl de vim-modus is uitgeschakeld, print de letterlijke string null, en uw balk toont null aan de gebruiker. Voeg // empty toe aan elke selector, zodat een ontbrekende key helemaal niets print.

Sommige waarden zijn in het begin null. context_window.used_percentage en context_window.current_usage zijn null vóór het eerste API-antwoord, en current_usage keert terug naar null na /compact totdat de volgende aanroep deze opnieuw vult. Een contextpercentage op de balk heeft daarom // 0 nodig, anders leest het null gedurende de eerste seconden van elke sessie. Voordat u dat getal op een balk plaatst, is het nuttig om te weten hoe het contextvenster daadwerkelijk wordt gevuld.

De git-branch staat niet in de JSON. Geen enkel veld rapporteert dit. Elke branch op uw balk is afkomstig van uw script dat zelf git uitvoert.

Een statusregel-script dat degradeert in plaats van crasht

Dit is de versie voor kopiëren en plakken. Het script toont de hostnaam, de werkmap, de git-branch en de modelnaam. Elk veld heeft een fallback, waardoor zelfs een leeg JSON-object nog een bruikbare regel oplevert.

#!/bin/bash
# ~/.claude/statusline.sh
input=$(cat)

# Read one field. Prints nothing when the key is missing or null.
field() { printf '%s' "$input" | jq -r "$1 // empty" 2>/dev/null; }

HOST=$(hostname -s 2>/dev/null)
[ -z "$HOST" ] && HOST="host"

DIR=$(field '.workspace.current_dir')
[ -z "$DIR" ] && DIR=$(field '.cwd')
[ -z "$DIR" ] && DIR="$PWD"

MODEL=$(field '.model.display_name')
[ -z "$MODEL" ] && MODEL="claude"

SHORT="$DIR"
if [ -n "$HOME" ]; then
  case "$DIR" in
    "$HOME") SHORT="~" ;;
    "$HOME"/*) SHORT="~/${DIR#"$HOME"/}" ;;
  esac
fi

BRANCH=""
if git -C "$DIR" rev-parse --git-dir >/dev/null 2>&1; then
  BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null)
  [ -z "$BRANCH" ] && BRANCH="detached"
fi

CYAN=$'\033[36m'
YELLOW=$'\033[33m'
DIM=$'\033[2m'
RESET=$'\033[0m'

LINE="${CYAN}${HOST}${RESET} ${SHORT}"
[ -n "$BRANCH" ] && LINE="${LINE} ${YELLOW}${BRANCH}${RESET}"
LINE="${LINE} ${DIM}${MODEL}${RESET}"

printf '%s\n' "$LINE"

Elke leesactie verloopt via field, waaraan // empty wordt toegevoegd. Hierdoor resulteert een hernoemde of verwijderde sleutel in een lege string en levert de volgende regel een standaardwaarde. De map valt terug van workspace.current_dir naar cwd naar $PWD. De branch wordt opgehaald uit git -C "$DIR" in plaats van een kale git, zodat de branch altijd overeenkomt met de map die de balk toont.

Sla het bestand op en maak het uitvoerbaar:

chmod +x ~/.claude/statusline.sh

De uitvoeringsbit is niet optioneel. Claude Code voert het commando uit via een shell, dus een script zonder +x faalt met Permission denied, produceert geen stdout en de regel blijft leeg zonder zichtbare foutmelding.

jq parseert JSON op de opdrachtregel en is niet geïnstalleerd op een verse Ubuntu-server:

sudo apt update && sudo apt install -y jq

Wijs vervolgens de instelling naar het script, met gebruik van het eerste settings.json-blok hierboven.

Test het script voordat u het vertrouwt

Voer het script tweemaal handmatig uit. De eerste keer met een normaal sessie-object:

echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.sh

U krijgt de hostnaam, gevolgd door /srv/api en daarna Opus. Er verschijnt geen branch, omdat /srv/api op uw machine waarschijnlijk geen git-repository is.

De tweede keer voert u de degradatietest uit; dit is de stap die vaak wordt overgeslagen:

echo '{}' | ~/.claude/statusline.sh

Een leeg object is het slechtst denkbare scenario bij een schemawijziging. De regel wordt nog steeds afgedrukt: de hostnaam, de huidige map uit $PWD en het woord claude op de plek waar de modelnaam hoort te staan. Niets crasht en er wordt nergens null afgedrukt. Een script dat voor deze test slaagt, overleeft het hernoemen van een veld, omdat een hernoemd veld en een ontbrekend veld voor uw script hetzelfde resultaat opleveren.

Wat u zou moeten zien

De statusregel wordt op een eigen rij boven de ingebouwde voettekst-badges weergegeven en vervangt deze niet. Bij een werkende configuratie bestaat deze uit één rij: de korte hostnaam in cyaan, gevolgd door de werkmap waarbij uw thuismap is ingeklapt tot ~, daarna de branch-naam in geel wanneer de map een git-repository is, en tot slot de modelnaam in een gedimde kleur. Iets dat lijkt op web-01 ~/api main Opus, met die vier onderdelen in kleur.

De rij voert uw script opnieuw uit wanneer een sessie start, inclusief een hervatting, wanneer er een nieuw assistent-bericht binnenkomt, nadat /compact is voltooid, wanneer de permissiemodus wijzigt, wanneer de vim-modus schakelt, en bij een refreshInterval-tick als u die heeft ingesteld. Updates worden met 300 ms vertraagd (debounced), zodat een reeks wijzigingen het script slechts één keer uitvoert. De balk verbergt zichzelf tijdens autocomplete, het helpmenu en permissievragen, en keert daarna terug.

Waarom de hostnaam op de eerste plaats hoort

Wanneer u agents op meer dan één server tegelijk draait, is de terminal het enige dat aangeeft waar u zich bevindt, en terminals zijn onbetrouwbaar. Open een tweede ssh-verbinding vanuit een tmux-paneel en de venstertitel behoudt vaak de oude naam, omdat de titel wordt ingesteld door een shell die niet heeft opgemerkt dat deze is verplaatst. Laat Claude Code draaien in een losgekoppelde tmux-sessie op een VPS en koppel een dag later opnieuw; er is op het scherm niets dat de build-server onderscheidt van de productie-omgeving.

De statusregel is anders omdat deze door Claude Code zelf wordt gerenderd, per sessie, op basis van gegevens die die sessie vasthoudt. Deze kan niet worden overgenomen van het verkeerde paneel of verouderd raken door een shell-prompt die niet is ververst. Wat er staat, is de machine waarop de agent bestanden schrijft.

Geef elke server een eigen kleur zodat u deze herkent voordat u de tekst leest. Twee regels, toegevoegd boven de LINE=-toewijzing:

CODE=$(printf '%s' "$HOST" | cksum | cut -d' ' -f1)
HOST_COLOR=$(printf '\033[%dm' "$((31 + CODE % 6))")

Gebruik vervolgens ${HOST_COLOR} in plaats van ${CYAN}. cksum print een checksum van de hostnaam, waardoor een specifieke naam altijd wordt gekoppeld aan dezelfde kleur in het bereik 31 tot 36, wat staat voor rood tot cyaan. Kopieer hetzelfde script naar elke machine en elke machine labelt zichzelf.

De directory verdient zijn plek om dezelfde reden. /srv/api en /srv/api-staging liggen slechts één toetsaanslag uit elkaar in een ssh-commando, maar het verschil in effect is een volledig incident. Het model en de branch zijn de andere twee elementen die de ruimte waard zijn: het model vertelt u welke sessie u heeft hervat, en de branch vertelt u of de agent op het punt staat een commit uit te voeren naar main.

Een klein scherm maakt dit alles duidelijker, aangezien er geen venstertitel is om op terug te vallen. Als dat uw configuratie is, raadpleeg dan Claude Code aansturen vanaf een telefoon.

Houd het script snel

Uw script wordt bij elk bericht van de assistent uitgevoerd en Claude Code annuleert een lopende uitvoering wanneer er een nieuwe update binnenkomt. Een traag script toont daarom verouderde tekst of helemaal geen tekst.

Elke jq-aanroep kost enkele milliseconden. git is het onderdeel dat traag wordt: git status in een grote repository met een koude cache duurt honderden milliseconden. Het bovenstaande script vermijdt bewust git status en roept git branch --show-current aan, dat .git/HEAD leest en onmiddellijk terugkeert.

Als u iets zwaarders toevoegt, cache dit dan in een bestand en ververs het elke paar seconden. Gebruik de sessie als sleutel voor het bestand:

CACHE="/tmp/statusline-$(field '.session_id')"

Gebruik session_id, niet $$. $$ is het proces-ID van uw script, dat bij elke aanroep anders is. Een cache die hierop gebaseerd is, wordt dus nooit gevonden en u betaalt elke keer de volledige kosten. session_id is stabiel voor de gehele sessie en verschilt per sessie, waardoor twee Claude Code-sessies in twee verschillende repositories niet elkaars gecachte branch-naam kunnen lezen.

Nog een limiet die het vermelden waard is: tput cols werkt niet binnen een statusline-script. Claude Code vangt de uitvoer op in plaats van uw script aan de terminal te koppelen, waardoor breedtedetectie niets heeft om te meten. Claude Code stelt de omgevingsvariabelen COLUMNS en LINES in voordat het commando wordt uitgevoerd, vanaf versie v2.1.153 en later. Lees dus $COLUMNS wanneer u moet bepalen hoeveel tekst u wilt afdrukken.

Waarom de statusregel leeg blijft

Er verschijnt helemaal niets. Controleer de uitvoeringsrechten (execute bit) met ls -l ~/.claude/statusline.sh en voer het script vervolgens handmatig uit met de bovenstaande mock-input. Als het script wel een regel in de shell print, maar niet in Claude Code, begin dan met claude --debug. Dit logt de exit-code en de stderr van de eerste statusregel-run van de sessie.

Het debug-logbestand meldt Status line command skipped: workspace trust not accepted. De statusregel voert een shell-commando uit en valt daarom onder dezelfde workspace-vertrouwensgrens als hooks. Zolang u het vertrouwensdialoogvenster voor die map niet accepteert, wordt het commando niet uitgevoerd. Dit komt vaak voor op een VPS, waar elke nieuwe clone een map is die Claude Code nog niet eerder heeft gezien. Herstart Claude Code in die map en accepteer het dialoogvenster.

Alles is leeg en disableAllHooks is ingesteld. "disableAllHooks": true in settings.json schakelt de statusregel ook uit, omdat dit dezelfde shell-executiebeperking betreft. Verwijder deze instelling of zet deze op false.

De regel print null. Een jq-selector heeft een sleutel bereikt die ontbreekt of null is, en jq -r print null als de vier tekens null. Voeg // empty toe voor tekst en // 0 voor getallen.

De regel wordt direct leeg na het bewerken van het script. Een commando dat met een non-zero status afsluit of niets print, maakt de regel leeg. De gebruikelijke oorzaak is een laatste regel zoals [ -n "$BRANCH" ] && LINE="...", die 1 teruggeeft als de branch leeg is en de exit-code van het gehele script daarmee beïnvloedt. Zorg dat printf als laatste staat, of voeg exit 0 toe.

Escape-codes worden getoond als letterlijke tekst, zoals \e]8;; op de balk. Gebruik printf '%b' in plaats van echo -e. Klikbare OSC 8-links vereisen bovendien een terminal die deze ondersteunt; tmux of SSH kunnen de sequenties strippen, dus eenvoudige kleuren zijn de veiligere keuze op een externe server.

De rechterkant van de regel is afgesneden. Systeemmeldingen en de token-teller in verbose-modus delen die regel vanaf de rechterkant, en een smalle terminal verliest de overlap. Houd de output kort. Voor een nauwkeurige weergave van het verbruik in plaats van een getal op een balk, zie hoe Claude Code tokens telt.

FAQ

Waar bevindt zich de instelling voor de statusregel van Claude Code?

In settings.json, als een statusLine-blok waarbij type is ingesteld op "command" en command is ingesteld op een scriptpad of een shell-commando. Gebruikersinstellingen staan in ~/.claude/settings.json en zijn van toepassing op elk project op die machine. Projectinstellingen staan in .claude/settings.json binnen de repository en hebben voorrang voor die map. Instellingen worden automatisch opnieuw geladen, maar een wijziging wordt pas zichtbaar bij de volgende update-trigger, zoals uw volgende bericht.

Waarom is mijn statusregel van Claude Code leeg?

Vier oorzaken verklaren bijna alle gevallen. Het script mist het uitvoeringsrecht (execute bit), waardoor de shell Permission denied teruggeeft en er niets naar stdout gaat. Het dialoogvenster voor workspace-vertrouwen is nooit geaccepteerd en claude --debug logt Status line command skipped: workspace trust not accepted. disableAllHooks is true, wat de statusregel onder dezelfde voorwaarde uitschakelt. Of het script sluit af met een non-zero exitcode, waardoor de regel leeg blijft. Test het eerst handmatig: echo '{}' | ~/.claude/statusline.sh moet iets afdrukken.

Bevat de JSON van de statusregel de git-branch?

Nee. De JSON bevat sessiestatus zoals het model, de workspace-mappen, getallen voor het contextvenster en de kosten. Niets daarin rapporteert git. Een branch op uw balk is afkomstig van uw eigen script dat git branch --show-current aanroept. Geef de map uit de JSON door met git -C "$DIR", zodat de branch altijd overeenkomt met de map die de balk toont.

Kost een statusregel tokens of vertraagt het de sessie?

Het kost geen tokens, omdat het script lokaal draait en de uitvoer nooit naar het model wordt verzonden. Snelheid is uw eigen verantwoordelijkheid. Het commando draait bij elk bericht van de assistent met een debounce van 300 ms, en Claude Code annuleert een lopende uitvoering wanneer er een nieuwe update binnenkomt. Een script dat een volle seconde duurt, toont dus verouderde tekst. Vermijd git status in grote repositories en cache alles wat traag is in een bestand dat is gekoppeld aan session_id.

Hoe toon ik een andere statusregel op elke server?

Gebruik één script en laat dit de machine uitlezen. Het bovenstaande script drukt $HOSTNAME af met hostname -s als fallback, zodat hetzelfde bestand gekopieerd naar elke machine elk exemplaar correct labelt, en de checksum-kleurentruc geeft elke hostnaam zijn eigen kleur. Als een server een andere lay-out nodig heeft, plaats dan een statusLine-blok in de projectinstellingen van de repository waarin u op die machine werkt, aangezien projectinstellingen de gebruikersinstellingen voor die map overschrijven.