SSD Nodes Learn 🎉 VPS dès $4.99/mois
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-07

Configurer une statusline Claude Code sur un VPS

Affichez le hostname, le répertoire, la branche Git et le modèle sous le prompt grâce à statusLine, pour éviter les erreurs sur le mauvais serveur.

Ce qu’affiche une statusline Claude Code

Une statusline Claude Code est une ligne située sous le prompt. Elle affiche la sortie d’un script que vous écrivez. Vous ajoutez un bloc statusLine à settings.json et vous l’associez à une commande. Claude Code exécute cette commande, lui transmet l’état de la session au format JSON sur l’entrée standard, puis affiche tout ce que la commande écrit sur la sortie standard.

C’est tout le contrat. Votre script lit le JSON sur stdin et écrit du texte sur stdout. Il s’exécute sur votre machine. Rien de ce qu’il affiche n’est envoyé au modèle. Il ne consomme donc aucun token.

Sur un laptop avec un seul projet, c’est surtout décoratif. Sur trois serveurs, c’est une protection. Chaque session Claude Code se présente de la même manière dans chaque terminal. Quatre fenêtres SSH sans libellé suffisent donc pour appliquer une migration sur le mauvais serveur. Une statusline qui commence par le hostname élimine ce type d’erreur.

Emplacement du paramètre statusLine dans settings.json

Ajoutez-le à vos paramètres utilisateur dans ~/.claude/settings.json. Il s’applique à tous les projets de cette machine. Les paramètres du projet dans .claude/settings.json, à l’intérieur d’un dépôt, fonctionnent également et sont prioritaires pour ce répertoire.

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

type vaut toujours "command". La valeur command est exécutée par un shell. Il peut donc s’agir du chemin d’un script ou d’une commande simple. Vérifiez le fonctionnement de la configuration avant d’écrire un script :

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

Lancez Claude Code et envoyez un message. La barre située sous l’invite affiche alors le nom d’hôte court du serveur. Si elle reste vide, le problème vient du paramètre ou de la boîte de dialogue de confiance, pas de votre script. Consultez la section « Pourquoi la statusline reste vide » ci-dessous.

Trois clés facultatives existent depuis août 2026. padding ajoute un espacement horizontal en caractères et vaut 0 par défaut. refreshInterval relance la commande toutes les N secondes, en plus des déclencheurs habituels, avec un minimum de 1. Utilisez-la uniquement lorsque la ligne affiche une horloge ou une autre valeur qui change pendant que la session reste inactive. hideVimModeIndicator masque le texte -- INSERT -- intégré lorsque votre propre script affiche déjà le mode vim.

Quelles données le script de statusline reçoit-il ?

Ne faites confiance à aucune liste de champs que vous trouvez, y compris sur cette page. Capturez l’objet réel envoyé par votre version. Écrivez un script temporaire qui enregistre stdin dans un fichier :

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

Pointez statusLine.command vers ce fichier, démarrez une session et envoyez un message. La barre lit captured. Examinez maintenant les données reçues :

jq . /tmp/statusline-input.json

Vous disposez ainsi de la structure exacte de votre build. Vous pouvez recommencer cette opération après chaque mise à jour qui modifie cette structure.

Les éléments stables, selon la documentation disponible en août 2026, sont des objets imbriqués et non des clés plates. model contient id et display_name. workspace contient current_dir et project_dir : current_dir indique le répertoire actuel de la session, project_dir celui depuis lequel elle a été lancée, et les deux valeurs diffèrent lorsque le répertoire de travail change pendant la session. Le cwd de premier niveau contient la même valeur que workspace.current_dir. context_window contient le nombre de tokens ainsi qu’un used_percentage précalculé. cost contient total_cost_usd et les compteurs de durée. session_id reste stable pendant toute la session et est unique entre les sessions, ce qui est utile pour la mise en cache ultérieure.

Trois règles permettent à un script de rester compatible malgré les changements de schéma.

Certaines clés sont absentes et non nulles. vim, agent, pr, worktree et effort apparaissent uniquement lorsque la fonctionnalité correspondante est active. La lecture de .vim.mode avec jq -r lorsque le mode vim est désactivé affiche la chaîne littérale null, et votre barre affiche null à l’utilisateur. Ajoutez // empty à chaque sélecteur afin qu’une clé absente n’affiche rien.

Certaines valeurs sont nulles au début. context_window.used_percentage et context_window.current_usage sont nulles avant la première réponse de l’API, et current_usage redevient nul après /compact jusqu’à ce que l’appel suivant lui attribue une nouvelle valeur. Un pourcentage de contexte affiché dans la barre nécessite donc // 0 ; sinon, la barre affiche null pendant les premières secondes de chaque session. Avant d’afficher ce nombre dans une barre, il est utile de comprendre comment la fenêtre de contexte se remplit réellement.

La branche git ne figure pas dans le JSON. Aucun champ ne l’indique. Toute branche affichée dans votre barre provient de votre script, qui exécute lui-même git.

Un script de statusline qui se dégrade au lieu de tomber en panne

Voici la version à copier-coller. Elle affiche le hostname, le répertoire de travail, la branche Git et le nom du modèle. Chaque champ dispose d’une valeur de repli. Même un objet JSON vide produit donc une ligne utilisable.

#!/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"

Chaque lecture passe par field, qui ajoute // empty. Une clé renommée ou supprimée produit ainsi une chaîne vide, puis la ligne suivante fournit une valeur par défaut. Pour le répertoire, les valeurs de repli sont utilisées dans l’ordre workspace.current_dir, cwd, puis $PWD. La branche provient de git -C "$DIR" et non d’un simple git. Elle correspond donc toujours au répertoire affiché par la barre.

Enregistrez le fichier, puis rendez-le exécutable :

chmod +x ~/.claude/statusline.sh

Le bit d’exécution est obligatoire. Claude Code exécute la commande via un shell. Un script dépourvu de +x échoue avec Permission denied, ne produit aucune sortie standard et laisse la ligne vide, sans erreur visible.

jq analyse le JSON sur la ligne de commande. Il n’est pas installé sur un serveur Ubuntu fraîchement installé :

sudo apt update && sudo apt install -y jq

Pointez ensuite le paramètre vers le script, en utilisant le premier bloc settings.json ci-dessus.

Tester le script avant de lui faire confiance

Exécutez-le deux fois manuellement. Commencez avec un objet de session normal :

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

Vous obtenez le nom d’hôte, puis /srv/api, puis Opus. Aucune branche ne s’affiche, car /srv/api sur votre machine n’est probablement pas un dépôt Git.

Effectuez ensuite le test de dégradation, celui que l’on oublie souvent :

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

Un objet vide représente le pire cas qu’une modification de schéma puisse vous transmettre. La ligne s’affiche toujours : le nom d’hôte, le répertoire courant de $PWD et le mot claude à l’emplacement du nom du modèle. Rien ne plante et rien n’affiche null. Un script qui réussit ce test résiste au renommage d’un champ, car pour votre script, un champ renommé et un champ manquant représentent le même événement.

Ce que vous devez voir

La ligne d’état s’affiche sur sa propre ligne, au-dessus des badges intégrés du pied de page, sans les remplacer. Dans une configuration fonctionnelle, elle comporte quatre éléments : le nom d’hôte court en cyan, puis le répertoire de travail avec votre répertoire personnel réduit à ~, ensuite le nom de la branche en jaune lorsque le répertoire est un dépôt git, et enfin le nom du modèle en atténué. Le résultat doit être proche de web-01 ~/api main Opus, avec ces quatre éléments colorés.

La ligne réexécute votre script au démarrage d’une session, y compris lors d’une reprise, lorsqu’un nouveau message de l’assistant arrive, après la fin de /compact, lorsque le mode d’autorisation change, lorsque le mode vim est activé ou désactivé, et à chaque intervalle de refreshInterval si vous en définissez un. Les mises à jour sont regroupées pendant 300 ms : une série de changements déclenche donc une seule exécution du script. La barre est masquée pendant la saisie semi-automatique, l’ouverture du menu d’aide et l’affichage des demandes d’autorisation, puis elle réapparaît.

Pourquoi le nom d’hôte doit apparaître en premier

Lorsque plusieurs serveurs exécutent des agents, le terminal est le seul élément qui indique où vous vous trouvez, et les terminaux peuvent être trompeurs. Ouvrez une deuxième connexion ssh depuis un volet tmux : le titre de la fenêtre conserve souvent l’ancien nom, car il est défini par un shell qui n’a jamais détecté le changement. Laissez Claude Code s’exécuter dans une session tmux détachée sur un VPS, puis rattachez-vous à la session le lendemain : rien à l’écran ne distingue le serveur de build du serveur de production.

La statusline est différente, car Claude Code la génère lui-même pour chaque session, à partir des données détenues par cette session. Elle ne peut pas être héritée du mauvais volet ni rester obsolète parce qu’une invite de shell n’a pas été actualisée. Elle indique le serveur sur lequel l’agent écrit les fichiers.

Attribuez une couleur différente à chaque serveur pour le reconnaître avant même de lire son nom. Ajoutez ces deux lignes au-dessus de l’affectation LINE= :

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

Utilisez ensuite ${HOST_COLOR} à la place de ${CYAN}. cksum affiche une somme de contrôle du nom d’hôte. Un nom donné correspond donc toujours à la même couleur dans la plage 31 à 36, du rouge au cyan. Copiez le même script sur chaque serveur : chacun affichera automatiquement son propre nom.

Le répertoire est utile pour la même raison. /srv/api et /srv/api-staging ne nécessitent qu’une touche de différence dans une commande ssh, mais leurs conséquences peuvent être très différentes lors d’un incident. Le modèle et la branche sont les deux autres informations qui justifient l’espace utilisé. Le modèle indique la session reprise, et la branche indique si l’agent est sur le point de valider des modifications dans main.

Un petit écran rend ces informations encore plus importantes, car vous ne pouvez pas compter sur le titre de la fenêtre. Si c’est votre configuration, consultez piloter Claude Code depuis un téléphone.

Accélérez le script

Votre script s’exécute à chaque message de l’assistant, et Claude Code annule l’exécution en cours lorsqu’une nouvelle mise à jour arrive. Un script lent affiche donc un texte obsolète, ou n’affiche rien.

Chaque appel à jq prend quelques millisecondes. git est la partie qui ralentit : git status dans un dépôt volumineux avec un cache froid prend des centaines de millisecondes. Le script ci-dessus évite volontairement git status et appelle git branch --show-current, qui lit .git/HEAD et renvoie immédiatement le résultat.

Si vous ajoutez une opération plus lourde, mettez son résultat en cache dans un fichier et actualisez-le toutes les quelques secondes. Utilisez la session comme clé du fichier :

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

Utilisez session_id, et non $$. $$ est l’ID de processus de votre script. Il est différent à chaque exécution, donc un cache utilisant cet ID comme clé n’est jamais utilisé et vous payez le coût complet à chaque fois. session_id reste stable pendant toute la session et diffère d’une session à l’autre. Deux sessions Claude Code exécutées dans deux dépôts différents ne peuvent donc pas lire le nom de branche mis en cache par l’autre session.

Une dernière limite mérite d’être connue : tput cols ne fonctionne pas dans un script de statusline. Claude Code capture la sortie au lieu d’attacher votre script au terminal. La détection de la largeur n’a donc rien à mesurer. Claude Code définit les variables d’environnement COLUMNS et LINES avant d’exécuter la commande, dans la version v2.1.153 et les versions ultérieures. Lisez donc $COLUMNS lorsque vous devez déterminer la quantité de texte à afficher.

La ligne d’état reste vide

Rien ne s’affiche. Vérifiez le bit d’exécution avec ls -l ~/.claude/statusline.sh, puis exécutez le script manuellement avec l’entrée simulée ci-dessus. S’il affiche une ligne dans le shell, mais pas dans Claude Code, commencez par claude --debug, qui journalise le code de sortie et la sortie d’erreur de la première exécution de la ligne d’état pendant la session.

Le journal de débogage indique Status line command skipped: workspace trust not accepted. La ligne d’état exécute une commande shell. Elle est donc soumise au même mécanisme de confiance de l’espace de travail que les hooks. Tant que vous n’avez pas accepté la boîte de dialogue de confiance pour ce répertoire, la commande ne s’exécute pas. Ce cas est fréquent sur un VPS, où chaque nouveau clone se trouve dans un répertoire que Claude Code n’a pas encore rencontré. Redémarrez Claude Code dans ce répertoire et acceptez la boîte de dialogue.

Tout est vide et disableAllHooks est défini. "disableAllHooks": true dans settings.json désactive également la ligne d’état, car il s’agit du même mécanisme d’autorisation pour l’exécution du shell. Supprimez-le ou définissez-le sur false.

La ligne affiche null. Un sélecteur jq a atteint une clé absente ou nulle, et jq -r affiche null sous la forme des quatre caractères null. Ajoutez // empty pour le texte et // 0 pour les nombres.

La ligne devient vide dès que vous modifiez le script. Une commande qui se termine avec un code différent de zéro, ou qui n’affiche rien, vide la ligne. La cause habituelle est une dernière ligne comme [ -n "$BRANCH" ] && LINE="...", qui renvoie 1 lorsque la branche est vide et transmet ce code de sortie à l’ensemble du script. Laissez printf en dernière position ou ajoutez exit 0.

Les codes d’échappement apparaissent sous forme de texte littéral, par exemple \e]8;; dans la barre. Utilisez printf '%b' au lieu de echo -e. Les liens OSC 8 cliquables nécessitent également un terminal compatible. tmux ou SSH peut supprimer ces séquences. Sur un système distant, les couleurs simples sont donc un choix plus sûr.

La partie droite de la ligne est tronquée. Les notifications système et le compteur de tokens du mode verbeux partagent cette ligne depuis la droite. Dans un terminal étroit, ils se chevauchent. Gardez la sortie courte. Pour obtenir un suivi réel de l’utilisation plutôt qu’un nombre dans une barre, consultez comment Claude Code compte les tokens.

FAQ

Où se trouve le paramètre de ligne d’état de Claude Code ?

Dans settings.json, sous la forme d’un bloc statusLine avec type défini sur "command" et command défini sur un chemin de script ou une commande shell. Les paramètres utilisateur se trouvent dans ~/.claude/settings.json et s’appliquent à tous les projets de cette machine. Les paramètres du projet se trouvent dans .claude/settings.json, à l’intérieur du dépôt, et sont prioritaires pour ce répertoire. Les paramètres sont rechargés automatiquement, mais une modification n’est visible qu’au prochain déclenchement de mise à jour, par exemple à votre prochain message.

Pourquoi ma ligne d’état Claude Code est-elle vide ?

Quatre causes couvrent presque tous les cas. Le script n’a pas le bit d’exécution, donc le shell renvoie Permission denied et rien n’est envoyé sur stdout. La boîte de dialogue de confiance de l’espace de travail n’a jamais été validée, et claude --debug journalise Status line command skipped: workspace trust not accepted. disableAllHooks est true, ce qui désactive la ligne d’état avec le même contrôle. Enfin, le script se termine avec un code différent de zéro, ce qui vide la ligne. Testez-le d’abord manuellement : echo '{}' | ~/.claude/statusline.sh doit afficher quelque chose.

Le JSON de la ligne d’état contient-il la branche git ?

Non. Le JSON contient l’état de la session, notamment le modèle, les répertoires de l’espace de travail, les valeurs de la fenêtre de contexte et le coût. Il ne contient aucune information sur git. La branche affichée dans votre barre vient de votre propre script, qui appelle git branch --show-current. Transmettez-lui le répertoire depuis le JSON avec git -C "$DIR", afin que la branche corresponde toujours au répertoire affiché par la barre.

Une ligne d’état consomme-t-elle des tokens ou ralentit-elle la session ?

Elle ne consomme aucun token, car le script s’exécute localement et sa sortie n’est jamais envoyée au modèle. La rapidité dépend de vous. La commande s’exécute à chaque message de l’assistant avec un debounce de 300 ms. Claude Code annule l’exécution en cours lorsqu’une nouvelle mise à jour arrive. Ainsi, un script qui prend une seconde entière affiche un texte obsolète. Évitez git status dans les dépôts volumineux et mettez en cache dans un fichier tout ce qui est lent, en utilisant session_id comme clé.

Comment afficher une ligne d’état différente sur chaque serveur ?

Conservez un seul script et laissez-le détecter la machine. Le script ci-dessus affiche $HOSTNAME, avec hostname -s comme valeur de secours. Le même fichier copié sur chaque serveur identifie donc correctement chacun d’eux. L’astuce de couleur basée sur la somme de contrôle donne aussi à chaque hostname sa propre couleur. Si un serveur nécessite une mise en page différente, ajoutez un bloc statusLine dans les paramètres du projet du dépôt utilisé sur ce serveur, car les paramètres du projet sont prioritaires sur les paramètres utilisateur pour ce répertoire.