feat(statusline): show context-window usage % in the status line
Adds .claude/statusline.sh (reads context_window.used_percentage + context_window_size straight from the statusLine JSON; green<70/yellow/red bar) and wires it via .claude/settings.json statusLine. Committed in-repo so it follows boma to any clone, matching how .claude/ already tracks hooks + plugins. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5d14efc864
commit
959f9b30b5
2 changed files with 68 additions and 0 deletions
|
|
@ -69,5 +69,10 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusLine": {
|
||||
"type": "command",
|
||||
"command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/statusline.sh\"",
|
||||
"padding": 0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
63
.claude/statusline.sh
Executable file
63
.claude/statusline.sh
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Claude Code statusLine — shows working dir, model, and context-window usage.
|
||||
# Wired via .claude/settings.json (statusLine.command). Receives the statusLine
|
||||
# JSON on stdin; first stdout line is rendered (ANSI colour supported).
|
||||
#
|
||||
# Context usage comes straight from the input JSON — no transcript parsing:
|
||||
# .context_window.used_percentage pre-calculated % of the window in use (input side)
|
||||
# .context_window.context_window_size window size in tokens (1000000 for the 1M models)
|
||||
# verified: Claude Code statusLine schema · code.claude.com/docs/en/statusline · 2026-06-17
|
||||
#
|
||||
# Fails soft: any parse problem prints nothing and exits 0 (never breaks the prompt).
|
||||
set -uo pipefail
|
||||
|
||||
input=$(cat 2>/dev/null) || exit 0
|
||||
command -v jq >/dev/null 2>&1 || exit 0
|
||||
|
||||
# pct<TAB>window<TAB>dir-basename<TAB>model-name (used_percentage preferred,
|
||||
# else derived from current_usage, else 0). @tsv keeps spaces in the dir safe.
|
||||
parsed=$(printf '%s' "$input" | jq -r '
|
||||
(.workspace.current_dir // .cwd // "" | sub(".*/"; "")) as $dir
|
||||
| (.model.display_name // "?") as $model
|
||||
| (.context_window.context_window_size // 200000) as $win
|
||||
| (
|
||||
if (.context_window.used_percentage // null) != null then
|
||||
.context_window.used_percentage
|
||||
elif (.context_window.current_usage // null) != null then
|
||||
((.context_window.current_usage.input_tokens
|
||||
+ (.context_window.current_usage.cache_creation_input_tokens // 0)
|
||||
+ (.context_window.current_usage.cache_read_input_tokens // 0)) / $win * 100)
|
||||
else 0 end | floor
|
||||
) as $pct
|
||||
| [$pct, $win, $dir, $model] | @tsv
|
||||
' 2>/dev/null) || exit 0
|
||||
[ -z "$parsed" ] && exit 0
|
||||
|
||||
IFS=$'\t' read -r pct win dir model <<<"$parsed"
|
||||
|
||||
# Human window label: 1000000 -> 1M, 200000 -> 200k, else Nk.
|
||||
case "$win" in
|
||||
1000000) wlabel="1M" ;;
|
||||
*) wlabel="$((win / 1000))k" ;;
|
||||
esac
|
||||
|
||||
# Colour the bar/percentage by pressure: green <70, yellow 70–89, red >=90.
|
||||
if [ "$pct" -ge 90 ]; then col=$'\033[31m' # red
|
||||
elif [ "$pct" -ge 70 ]; then col=$'\033[33m' # yellow
|
||||
else col=$'\033[32m' # green
|
||||
fi
|
||||
dim=$'\033[2m'; rst=$'\033[0m'
|
||||
|
||||
# 10-cell bar; clamp fill to [0,10] so an over-100 reading can't overflow.
|
||||
filled=$((pct / 10)); [ "$filled" -gt 10 ] && filled=10; [ "$filled" -lt 0 ] && filled=0
|
||||
bar=""
|
||||
for ((i = 0; i < 10; i++)); do
|
||||
if [ "$i" -lt "$filled" ]; then bar+="█"; else bar+="░"; fi
|
||||
done
|
||||
|
||||
printf '%s%s%s · %s · %s%s %d%%%s %sctx/%s%s\n' \
|
||||
"$dim" "$dir" "$rst" \
|
||||
"$model" \
|
||||
"$col" "$bar" "$pct" "$rst" \
|
||||
"$dim" "$wlabel" "$rst"
|
||||
Loading…
Add table
Reference in a new issue