authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-08-14 14:37:39-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-08-14 15:25:29-07:00
logdcd99802f7208519acf9dcb3d9434f55b12e5a4a
tree754eb659774eb68c934f586560a2a76c0cc15d0b
parent447cd421176ffd391aea18fe2a2b2db151d9a5ec
signature Signed by SSH key SHA256:cOKiuRFOeSRxne6EWgHtdQQSlBxjOXm2hOCFnCdLQbQ

clover: claude code status line


2 files changed, 84 insertions(+), 0 deletions(-)

users/clover/home.nix+6
......@@ -8,6 +8,7 @@ let
88 hostServer = false;
99 agentsFile = "${config.home.homeDirectory}/config/users/clover/AGENTS.md";
1010 simpleBrowserBridge = "${config.home.homeDirectory}/config/files/vscode-simple-browser-bridge";
11 claudeStatusline = "${config.home.homeDirectory}/config/users/clover/scripts/claude-statusline.sh";
1112in
1213{
1314 home = {
......@@ -51,6 +52,11 @@ in
5152 # of opencode's global AGENTS.md); point it at the same file.
5253 home.file.".claude/CLAUDE.md".source = config.lib.file.mkOutOfStoreSymlink agentsFile;
5354
55 # Referenced by the `statusLine.command` entry in ~/.claude/settings.json,
56 # which claude code rewrites itself and so stays unmanaged.
57 home.file.".claude/statusline-command.sh".source =
58 config.lib.file.mkOutOfStoreSymlink claudeStatusline;
59
5460 # Companion extension for the `open-in-vscode-browser` shim. Symlinked
5561 # (rather than copied) so edits to the source are live after a window reload.
5662 # macOS-only: the shim targets /usr/bin/open.
users/clover/scripts/claude-statusline.sh created+78
......@@ -0,0 +1,78 @@
1#!/bin/bash
2# Four segments: model, thinking/effort, context used %, rate-limit remaining.
3# Meters ramp cool -> hot (blue, cyan, green, yellow, red) as each stat grows big.
4input=$(cat)
5
6sep_color=240
7model_color=176
8thinking_color=108
9
10color_for_pct() {
11 local pct="${1%.*}"
12 if (( pct >= 85 )); then echo 203
13 elif (( pct >= 70 )); then echo 214
14 elif (( pct >= 50 )); then echo 114
15 elif (( pct >= 25 )); then echo 80
16 else echo 111
17 fi
18}
19
20humanize() {
21 local n=$1
22 if (( n >= 1000000 )); then
23 printf '%s' "$(awk -v n="$n" 'BEGIN{printf "%.1fM", n/1000000}' | sed 's/\.0M/M/')"
24 elif (( n >= 1000 )); then
25 printf '%dk' $(( n / 1000 ))
26 else
27 printf '%d' "$n"
28 fi
29}
30
31model=$(printf '%s' "$input" | jq -r '.model.display_name // ""')
32model_short=$(grep -oE 'Opus|Sonnet|Haiku' <<<"$model" | head -1)
33[[ -z "$model_short" ]] && model_short="$model"
34
35effort=$(printf '%s' "$input" | jq -r '.effort.level // ""')
36if [[ -n "$effort" ]]; then
37 thinking="$(tr '[:lower:]' '[:upper:]' <<<"${effort:0:1}")${effort:1}"
38elif [[ "$(printf '%s' "$input" | jq -r '.thinking.enabled // false')" == "true" ]]; then
39 thinking="On"
40else
41 thinking="Off"
42fi
43
44segments=("$(printf "\033[38;5;%sm%s\033[0m" "$model_color" "$model_short")" "$(printf "\033[38;5;%sm%s\033[0m" "$thinking_color" "$thinking")")
45
46ctx_pct=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')
47if [[ -n "$ctx_pct" ]]; then
48 read -r ctx_used ctx_size < <(printf '%s' "$input" | jq -r '.context_window | "\(.total_input_tokens // 0) \(.context_window_size // 0)"')
49 c=$(color_for_pct "$ctx_pct")
50 if (( ctx_size > 0 )); then
51 segments+=("$(printf "\033[38;5;%sm%.0f%% ctx (%s/%s)\033[0m" "$c" "$ctx_pct" "$(humanize "$ctx_used")" "$(humanize "$ctx_size")")")
52 else
53 segments+=("$(printf "\033[38;5;%sm%.0f%% ctx\033[0m" "$c" "$ctx_pct")")
54 fi
55fi
56
57five=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
58week=$(printf '%s' "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
59if [[ -n "$five" || -n "$week" ]]; then
60 limits=""
61 if [[ -n "$five" ]]; then
62 c=$(color_for_pct "$five")
63 limits+=$(printf "\033[38;5;%sm%.0f%% 5h\033[0m" "$c" "$(( 100 - ${five%.*} ))")
64 fi
65 if [[ -n "$week" ]]; then
66 [[ -n "$limits" ]] && limits+=$(printf " \033[38;5;%sm/\033[0m " "$sep_color")
67 c=$(color_for_pct "$week")
68 limits+=$(printf "\033[38;5;%sm%.0f%% 7d\033[0m" "$c" "$(( 100 - ${week%.*} ))")
69 fi
70 segments+=("$limits")
71fi
72
73sep=$(printf " \033[38;5;%sm·\033[0m " "$sep_color")
74line="${segments[0]}"
75for ((i = 1; i < ${#segments[@]}; i++)); do
76 line+="${sep}${segments[i]}"
77done
78printf '%s\n' "$line"