Suivi de l’usage de Claude Code en direct sous Windows

Ce guide explique comment afficher en permanence, sous le champ de saisie de Claude Code, le modèle, le dossier, la branche git, le remplissage du contexte, les tokens, le coût et la durée de la session. On utilise pour cela la status line, alimentée par un script PowerShell.

Résultat :

[Sonnet] 📁 mon-projet 🌿 main +2~1
████░░░░░░ 42% | ↑ 12.0k ↓ 3.0k | $0.50 | ⏱️ 1m 5s

Basé sur ce code linux. gamusta/live-claude-code-dashboard

Principe

Claude Code exécute une commande à chaque mise à jour de l’interface. Il lui envoie sur stdin un JSON décrivant la session (modèle, coût, contexte, durée…). Le script lit ce JSON et écrit sur stdout les lignes à afficher.

Prérequis

  • Windows 10 ou 11
  • PowerShell (powershell 5.1 est livré avec Windows, pwsh 7+ fonctionne aussi)
  • Git dans le PATH (optionnel, pour la branche et les fichiers modifiés)
  • Un terminal qui gère les couleurs ANSI et les emojis (Windows Terminal recommandé)

Étape 1 : créer le script

Créez C:\Users\<VOTRE_NOM>\.claude\statusline.ps1 :

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8

$ci = [System.Globalization.CultureInfo]::InvariantCulture
$raw = [Console]::In.ReadToEnd()
$j = $raw | ConvertFrom-Json

function Num($v) { 
    if ($null -eq $v) { 0 } else { [double]$v } 
}

$model = $j.model.display_name
$dir = $j.workspace.current_dir
$cost = Num $j.cost.total_cost_usd
$pct = [int][math]::Floor((Num $j.context_window.used_percentage))
$durMs = Num $j.cost.total_duration_ms
$inTok = Num $j.context_window.total_input_tokens
$outTok = Num $j.context_window.total_output_tokens

$e = [char]27
$CYAN = "$e[36m"
$GREEN = "$e[32m"
$YELLOW = "$e[33m"
$RED = "$e[31m"
$MAGENTA = "$e[35m"
$RESET = "$e[0m"

function Format-Tokens($t) {
    if ($t -ge 1000000) { return ([math]::Floor($t / 100000) / 10).ToString('0.0', $ci) + 'M' }
    if ($t -ge 1000) { return ([math]::Floor($t / 100) / 10).ToString('0.0', $ci) + 'k' }
    return [string][int]$t
}

# Couleur de la barre selon le remplissage du contexte
if ($pct -ge 90) { 
    $barColor = $RED 
} elseif ($pct -ge 70) { 
    $barColor = $YELLOW 
} else { 
    $barColor = $GREEN 
}

$filled = [math]::Min(10, [math]::Max(0, [int][math]::Floor($pct / 10)))
$bar = ([string][char]0x2588) * $filled + ([string][char]0x2591) * (10 - $filled)

$mins = [int][math]::Floor($durMs / 60000)
$secs = [int][math]::Floor(($durMs % 60000) / 1000)

# Infos git (si le dossier est un dépôt)
$branch = ''
$gitStatus = ''
$null = git rev-parse --git-dir 2>$null
if ($LASTEXITCODE -eq 0) {
    $name = git branch --show-current 2>$null
    if (-not $name) {
        $name = git rev-parse --short HEAD 2>$null # Fallback si HEAD est détaché
    }
    $branch = ' | ' + [char]::ConvertFromUtf32(0x1F33F) + " $name"
    $staged = @(git diff --cached --numstat 2>$null).Count
    $modified = @(git diff --numstat 2>$null).Count
    if ($staged -gt 0) { $gitStatus = "$GREEN+$staged$RESET" }
    if ($modified -gt 0) { $gitStatus += "$YELLOW~$modified$RESET" }
}

$folder = if ($dir) { Split-Path $dir -Leaf } else { '' }
$iFolder = [char]::ConvertFromUtf32(0x1F4C1)
$iTimer = [char]::ConvertFromUtf32(0x23F1) + [char]0xFE0F
$up = [char]0x2191
$down = [char]0x2193

Write-Output "$CYAN[$model]$RESET $iFolder $folder$branch $gitStatus"
$costFmt = '$' + $cost.ToString('0.00', $ci)
Write-Output "$barColor$bar$RESET $pct% | $CYAN$up $(Format-Tokens $inTok)$RESET $YELLOW$down $(Format-Tokens $outTok)$RESET | $MAGENTA$costFmt$RESET | $iTimer ${mins}m ${secs}s"

Étape 2 : déclarer la status line dans settings.json

Éditez C:\Users\<VOTRE_NOM>\.claude\settings.json et ajoutez :

{
  "statusLine": {
    "type": "command",
    "command": "powershell -NoProfile -ExecutionPolicy Bypass -File C:/Users/<VOTRE_NOM>/.claude/statusline.ps1",
    "padding": 2
  }
}

Points importants :

  • Ne mettez pas simplement le chemin du .ps1 comme commande. Claude Code passe par un shell (Git Bash). Un .ps1 n’est pas exécutable directement, donc la status line reste vide.
  • Appelez toujours powershell -File ... (ou pwsh -File ...).
  • Utilisez des / dans le chemin pour éviter d’échapper les \ dans le JSON.
  • -ExecutionPolicy Bypass évite le blocage par la politique d’exécution de Windows.
  • -NoProfile accélère le démarrage, ce qui compte car le script tourne très souvent.

Étape 3 : tester le script à la main

Dans PowerShell, simulez le JSON envoyé par Claude Code :

'{"model":{"display_name":"Sonnet"},"workspace":{"current_dir":"C:\\Users"},"cost":{"total_cost_usd":0.5,"total_duration_ms":65000},"context_window":{"used_percentage":42,"total_input_tokens":12000,"total_output_tokens":3000}}' | powershell -NoProfile -ExecutionPolicy Bypass -File C:/Users/<VOTRE_NOM>/.claude/statusline.ps1

Vous devez voir deux lignes colorées. Sinon, l’erreur s’affiche directement dans le terminal.

Étape 4 : relancer Claude Code

Fermez et relancez claude. La status line apparaît sous le champ de saisie et se met à jour en direct.

Ce que montre chaque élément

Élément Signification
[Sonnet] Modèle utilisé
📁 / 🌿 Dossier courant et branche git
+2~1 Fichiers indexés (vert) et modifiés (jaune)
Barre + % Remplissage de la fenêtre de contexte (vert < 70 %, jaune ≥ 70 %, rouge ≥ 90 %)
↑ / ↓ Tokens d’entrée et de sortie cumulés
$0.50 Coût estimé de la session
⏱️ Durée de la session

Pensez à lancer /compact ou /clear quand la barre passe au rouge.

Dépannage

Symptôme Cause probable Solution
Rien ne s’affiche Commande = chemin du .ps1 seul Utiliser powershell -File ...
Erreur de politique d’exécution ExecutionPolicy restrictive Ajouter -ExecutionPolicy Bypass
Caractères bizarres (â–ˆ, ðŸ“) Mauvais encodage Vérifier les deux lignes [Console]::...Encoding en tête de script, utiliser Windows Terminal
Pas de branche git Pas de dépôt, ou git absent du PATH Vérifier git --version
Affichage lent Profil PowerShell lourd, gros dépôt git Garder -NoProfile, ou retirer les appels git diff
Les modifications ne s’appliquent pas Réglage non rechargé Relancer Claude Code

Aller plus loin

  • Le JSON reçu contient d’autres champs (par exemple l’identifiant de session). Pour les voir, écrivez $raw dans un fichier de log depuis le script.
  • La commande /cost et la commande /status donnent aussi un récapitulatif ponctuel.
  • Pour un suivi de l’historique, sur plusieurs jours ou projets, regardez des outils externes comme ccusage (npx ccusage), qui analyse les logs locaux de ~/.claude.