Skip to content

Instantly share code, notes, and snippets.

@vilaca
Created June 26, 2026 13:40
Show Gist options
  • Select an option

  • Save vilaca/2b8b2d6b819e4106d2e219ff3b34e4d5 to your computer and use it in GitHub Desktop.

Select an option

Save vilaca/2b8b2d6b819e4106d2e219ff3b34e4d5 to your computer and use it in GitHub Desktop.
#!/bin/zsh
input=$(cat)
dir=$(echo "$input" | jq -r '.workspace.current_dir // .cwd')
model=$(echo "$input" | jq -r '.model.display_name // empty')
remaining=$(echo "$input" | jq -r '.context_window.remaining_percentage // empty')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
transcript=$(echo "$input" | jq -r '.transcript_path // empty')
# Message count - needed early for /clear detection
msgs=""
cache_pct=""
if [ -n "$transcript" ] && [ -f "$transcript" ]; then
msgs=$(wc -l < "$transcript" | tr -d ' ')
cache_pct=$(tac "$transcript" 2>/dev/null | jq -r 'select(.message.usage) | .message.usage | (.cache_read_input_tokens // 0) as $r | (.cache_creation_input_tokens // 0) as $w | (.input_tokens // 0) as $i | if ($r + $w + $i) > 0 then (100 * $r / ($r + $w + $i)) | floor else empty end' 2>/dev/null | head -1)
fi
# Per-turn cost: delta of cumulative cost since last invocation, stashed per session
# Also tracks a cost_baseline reset when /clear is detected (message count drops sharply)
turn_cost=""
cost_since_clear=""
if [ -n "$cost" ] && [ -n "$transcript" ]; then
session_id=$(basename "$transcript" .jsonl)
cache_file="/tmp/claude-statusline-${session_id}.cost"
prev_total=0
last_turn=0
prev_msgs=0
cost_baseline=0
if [ -f "$cache_file" ]; then
read -r prev_total last_turn prev_msgs cost_baseline < "$cache_file"
prev_total=${prev_total:-0}
last_turn=${last_turn:-0}
prev_msgs=${prev_msgs:-0}
cost_baseline=${cost_baseline:-0}
fi
# Detect /clear: message count dropped to less than half of previous (and prev was meaningful)
if [ -n "$msgs" ] && [ "$prev_msgs" -gt 5 ] 2>/dev/null; then
half_prev=$(awk -v p="$prev_msgs" 'BEGIN{printf "%d", p/2}')
if [ "$msgs" -lt "$half_prev" ] 2>/dev/null; then
cost_baseline="$cost"
last_turn=0
fi
fi
# Update only when cumulative cost has grown (a turn completed)
delta=$(awk -v a="$cost" -v b="$prev_total" 'BEGIN{printf "%.6f", a-b}')
if awk -v d="$delta" 'BEGIN{exit !(d > 0.0001)}'; then
last_turn="$delta"
printf "%s %s %s %s\n" "$cost" "$last_turn" "${msgs:-$prev_msgs}" "$cost_baseline" > "$cache_file"
else
printf "%s %s %s %s\n" "$prev_total" "$last_turn" "${msgs:-$prev_msgs}" "$cost_baseline" > "$cache_file"
fi
turn_cost="$last_turn"
cost_since_clear=$(awk -v a="$cost" -v b="$cost_baseline" 'BEGIN{printf "%.6f", a-b}')
fi
# Git info (skip optional lock to avoid conflicts)
branch=""
dirty=""
ahead_behind=""
worktree=""
if git -C "$dir" rev-parse --git-dir > /dev/null 2>&1; then
branch=$(git -C "$dir" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null)
if [ -n "$(git -C "$dir" --no-optional-locks status --porcelain 2>/dev/null)" ]; then
dirty="*"
fi
ab=$(git -C "$dir" --no-optional-locks rev-list --left-right --count '@{upstream}...HEAD' 2>/dev/null)
if [ -n "$ab" ]; then
behind=$(echo "$ab" | awk '{print $1}')
ahead=$(echo "$ab" | awk '{print $2}')
[ "$ahead" -gt 0 ] 2>/dev/null && ahead_behind="$ahead_behind⇡$ahead"
[ "$behind" -gt 0 ] 2>/dev/null && ahead_behind="$ahead_behind⇣$behind"
fi
# .git is a file (not dir) when inside a worktree
gitpath=$(git -C "$dir" rev-parse --git-dir 2>/dev/null)
case "$gitpath" in
*.git/worktrees/*) worktree=" (wt)" ;;
esac
fi
# Build the status line
printf "\033[33m%s\033[0m" "$dir"
if [ -n "$branch" ]; then
printf " \033[32m(%s%s%s)\033[0m" "$branch" "$dirty" "$ahead_behind"
fi
if [ -n "$worktree" ]; then
printf " \033[36m%s\033[0m" "$worktree"
fi
if [ -n "$model" ]; then
printf " \033[35m[%s]\033[0m" "$model"
fi
if [ -n "$remaining" ]; then
printf " \033[90mctx:%s%%\033[0m" "$(printf '%.0f' "$remaining")"
fi
if [ -n "$msgs" ]; then
if [ "$msgs" -gt 300 ] 2>/dev/null; then
color="31"
elif [ "$msgs" -gt 150 ] 2>/dev/null; then
color="33"
else
color="90"
fi
printf " \033[%smmsgs:%s\033[0m" "$color" "$msgs"
fi
if [ -n "$cache_pct" ]; then
printf " \033[90mcache:%s%%\033[0m" "$cache_pct"
fi
if [ -n "$turn_cost" ] && awk -v t="$turn_cost" 'BEGIN{exit !(t > 0)}'; then
printf " \033[90mΔ\$%s\033[0m" "$(awk -v t="$turn_cost" 'BEGIN{printf "%.3f", t}')"
fi
if [ -n "$cost_since_clear" ] && awk -v c="$cost_since_clear" 'BEGIN{exit !(c >= 0)}'; then
printf " \033[90m\$%s\033[0m" "$(awk -v c="$cost_since_clear" 'BEGIN{printf "%.2f", c}')"
elif [ -n "$cost" ]; then
printf " \033[90m\$%s\033[0m" "$(printf '%.2f' "$cost")"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment