Statusline para Claude Code, contexto a la vista en 15 minutos
Cómo construirte una statusline propia con una línea de shell script en settings.json. Modelo actual, porcentaje de contexto, rama de Git, ticker de costes. Con script de ejemplo concreto y las trampas que recogí en mi primer intento.
Claude Code normalmente solo te muestra lo imprescindible en el borde inferior. Qué modelo, si está activo el modo Vim, ya está. Cuando trabajas más rato, notas que echas cosas en falta. Cuánto porcentaje del contexto está consumido. En qué rama de Git estás. Cuánto suman los costes de la sesión en curso. Eso te lo puedes pintar tú mismo, con una línea en settings.json y un shell script. Te enseño cómo va y qué fallos de principiante cometí.
1. Entender cómo tictaquea la statusline
Claude Code llama cada pocos segundos a un comando de shell y muestra su salida stdout como statusline. El comando recibe JSON por stdin, con los datos más importantes de la sesión. Modelo, context window, working directory, token counts. Todo lo que necesitas para mostrar algo útil.
Eso significa: lo que puedas hacer en Bash o con jq, lo puedes mostrar en la statusline. Nombre del modelo, rama, costes, un punto verde si los tests están verdes, lo que sea.
2. La primera entrada en settings.json
Abre tu ~/.claude/settings.json y añade el bloque:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 2
}
}
type siempre es command, no hay otra cosa. command es o una ruta a un script o un comando de shell inline. padding mete espacio horizontal alrededor, opcional. También hay refreshInterval (milisegundos) si quieres que tu script se reinicie periódicamente y hideVimModeIndicator por si quieres ocultar el indicador de modo Vim integrado.
3. El script mínimo
Crea ~/.claude/statusline.sh, hazlo ejecutable, mete tres líneas:
#!/bin/bash
input=$(cat)
echo "$input" | jq -r '"[\(.model.display_name)] \(.workspace.current_dir | split("/") | last)"'
chmod +x ~/.claude/statusline.sh
Reinicia Claude Code, ves algo como [Opus 4.7] academy abajo. Nombre del modelo y último nombre de carpeta del working dir. No más, pero el plano está.
4. Pintar la utilización del contexto
Esta es la entrada que más necesito. Cuando estoy al 80 por ciento de contexto, tengo que pensar en compact o pestaña nueva. Para eso amplías la línea de jq:
#!/bin/bash
input=$(cat)
echo "$input" | jq -r '
"[\(.model.display_name)] " +
"\(.workspace.current_dir | split("/") | last) " +
"ctx:\(.context_window.used_percentage // 0 | floor)%"
'
Resultado: [Opus 4.7] academy ctx:62%. En cuanto el número pasa de 75, lo veo. En la primera versión había usado used_percentage sin el operador por defecto // 0, en la primera llamada tras el arranque el campo aún era null y la statusline no mostraba nada. Lección: pon defaults defensivos, el JSON de stdin no siempre está completo.
5. Rama de Git al lado
Cuando trabajas en un repo Git, la rama es un no-brainer. Pero cuidado, no siempre estás en un directorio Git, el comando tiene que aguantarlo.
branch=$(cd "$(echo "$input" | jq -r '.workspace.current_dir')" 2>/dev/null && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
[ -n "$branch" ] && branch=" git:$branch"
Luego lo cuelgas a la línea echo: ... ctx:62% git:main.
Trampa aquí: el cd tiene que estar en una subshell, si no cambias el directorio actual del script. Mi primer script no enmarcaba el cd en $(...) y de repente venían errores en cascada porque el siguiente comando se ejecutaba en otro sitio del esperado.
6. Meter un ticker de costes
Stdin entrega también total_cost_usd por si lo quieres mostrar. En mi caso eso corre para sesiones que duran más.
cost=$(echo "$input" | jq -r '.total_cost_usd // 0 | . * 100 | floor / 100')
[ "$cost" != "0" ] && cost=" \$$cost"
Cuidado: la estructura JSON exacta puede diferir entre versiones de Claude Code. Si el campo se llama distinto en tu caso, vuelca el stdin completo a un archivo de log una vez y mira. Un echo "$input" >> /tmp/statusline-debug.log es tu amigo.
7. Inline en vez de script
Si quieres ahorrarte el envoltorio del script, también puedes empaquetar el comando directamente en el settings.json. Se ve así:
{
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% ctx\"'"
}
}
Funciona, pero con statuslines más largas es una pesadilla por el escapado de JSON. A partir de tres filtros jq mejor archivo de script, así también tienes syntax highlighting en el editor.
8. Team setup con statusline de proyecto
La statusline también la puedes fijar a nivel de proyecto, metiendo el bloque en .claude/settings.json del repo en vez de en el global bajo ~/.claude/. Tiene sentido cuando el equipo quiere visualización uniforme, por ejemplo "queremos todos ver el color de la test suite".
Cuando llamas a scripts desde el repo, recuerda que los scripts tienen que aterrizar ejecutables en Git. git update-index --chmod=+x .claude/statusline.sh pone el bit de ejecutable, si no, no funciona tras git clone para los compañeros.
A mí me pasó: archivo de script comiteado, en local todo iba. Compañero hizo pull, sin chmod, la statusline se quedó vacía. Tres mensajes de Slack, lo encontramos. Desde entonces siempre con update-index --chmod=+x.
9. Debuggear cuando no llega nada
Tres cosas que me pasaron. Primera, settings.json roto tras edit, Claude Code no lo carga sin avisar. Solución: jq . ~/.claude/settings.json muestra errores de sintaxis. Segunda, el script no tiene executable bit, ls -la lo chequea, chmod +x lo arregla. Tercera, el script corre pero el stdout queda vacío por error de jq. Solución: pipear el script a mano con JSON de ejemplo.
echo '{"model":{"display_name":"Opus 4.7"},"workspace":{"current_dir":"/tmp/test"}}' | ~/.claude/statusline.sh
Si eso saca algo con sentido, el script está OK y el fallo viene del JSON de entrada de Claude Code. Ahí solo ayuda echo "$input" > /tmp/claude-statusline-input.log metido dentro y ver qué llega de verdad.
10. Qué viene después
Cuando la statusline corra, mira Gestionar el context window en Claude Code, porque la visualización es solo la mitad, reaccionar al número es la otra mitad. Si también quieres costes a la vista, Claude Code Cost Controls para daily drivers tiene la mecánica. Y si encima quieres ajustar el estilo de las respuestas, el playbook que encaja es Output Styles para Claude Code.
Para la capa de lessons encaja Hooks y Skills como refresher de concepto, porque la statusline es un side effect local y por tanto conceptualmente emparentada con el patrón hook.
Source
Statusline oficial: https://code.claude.com/docs/en/statusline