#!/usr/bin/env bash # CANONICAL COPY of the Claude Code statusline. Deployed to (and read from): # # ~/.claude/statusline-command.sh <- the LIVE path CC actually runs # # Install / update after editing here: # cp scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh # # Copies, not symlinks โ€” same rule as stacks/: this tree is intent, the live # path is reality, and they diverge until someone deploys. Diff them with # diff -u scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh # # It is version-controlled here because the althing v3 cutover broke it in a way # that was invisible: the segment gated on `command -v althing-cli`, a binary the # cutover deleted, so the ๐Ÿ“ฌ badge and ๐Ÿ”” bell silently vanished for every session # on the box. With 71 of 73 handles pull-only, that badge is the ONLY out-of-band # signal telling a session with no armed waiter that it has mail โ€” a dead # statusline made a working bus look like an empty one. # # Smoke test (CC pipes session JSON on stdin): # echo '{"model":{"display_name":"opus"},"workspace":{"current_dir":"/tmp"},"cwd":"/tmp"}' \ # | ALTHING_HANDLE= bash scripts/claude-statusline-command.sh # want: a leading `๐Ÿ“ฌ N`; and with an unreachable post office, degradation in # ~2s rather than a hang. # Claude Code statusline. Layout: # [๐Ÿ“ฌN] [๐Ÿ””/๐Ÿ”•] | โއ * โ†‘ | | ctx: | $ | 5h:% 7d:% # ctx% and rate-limit %s are threshold-colored: green <60, yellow 60-90, red >90. # All segments degrade gracefully (missing tool / non-git dir / no handle => segment omitted). input=$(cat) # --- threshold color: $1=numeric pct, $2=display text -> colored text --- color_pct() { local p="$1" txt="$2" c if awk "BEGIN{exit !($p < 60)}"; then c=$'\033[32m' # green <60 elif awk "BEGIN{exit !($p > 90)}"; then c=$'\033[31m' # red >90 else c=$'\033[33m' # yellow 60-90 fi printf '%s%s\033[0m' "$c" "$txt" } # --- reset countdown: $1=unix ts -> "1d3h"/"3h20m"/"45m" (2-unit; "now"/empty edge) --- reset_in() { local ts="$1" now delta d h m [ -z "$ts" ] && return now=$(date +%s) delta=$(( ts - now )) [ "$delta" -le 0 ] && { printf 'now'; return; } if [ "$delta" -ge 86400 ]; then d=$(( delta / 86400 )); h=$(( (delta % 86400) / 3600 )) if [ "$h" -gt 0 ]; then printf '%dd%dh' "$d" "$h"; else printf '%dd' "$d"; fi elif [ "$delta" -ge 3600 ]; then h=$(( delta / 3600 )); m=$(( (delta % 3600) / 60 )) if [ "$m" -gt 0 ]; then printf '%dh%dm' "$h" "$m"; else printf '%dh' "$h"; fi else printf '%dm' $(( delta / 60 )) fi } # --- one jq pass for every payload field --- # \x1f (unit separator) delimiter, NOT tab: tab is IFS-whitespace so `read` would # collapse consecutive tabs and shift every field after an empty one (e.g. a # session with no rate_limits). \x1f is non-whitespace -> empty fields preserved. IFS=$'\x1f' read -r model used_pct input_tok five_pct week_pct cwd fast cost_usd model_id five_reset week_reset < <( printf '%s' "$input" | jq -r '[ (.model.display_name // "unknown"), (.context_window.used_percentage // ""), (.context_window.total_input_tokens // 0), (.rate_limits.five_hour.used_percentage // ""), (.rate_limits.seven_day.used_percentage // ""), (.cwd // .workspace.current_dir // ""), (.fast_mode // false), (.cost.total_cost_usd // 0), (.model.id // ""), (.rate_limits.five_hour.resets_at // ""), (.rate_limits.seven_day.resets_at // "") ] | map(tostring) | join("")' ) [ -z "$model" ] && model="unknown" # --- model (compact) + fast-mode flag --- model="${model%% (*}" # "Opus 4.8 (1M context)" -> "Opus 4.8" [ "$fast" = "true" ] && model="โšก$model" # --- context % (colored) + absolute input tokens --- if [ -n "$used_pct" ]; then ctx_seg=$(color_pct "$used_pct" "ctx:$(printf '%.0f%%' "$used_pct")") else ctx_seg="ctx:--" fi if [ "${input_tok:-0}" -ge 1000 ] 2>/dev/null; then toks=$(awk "BEGIN{printf \"%.0fk\", ${input_tok}/1000}") else toks="${input_tok:-0}" fi # --- per-session cost (Claude Code's own cache/model-aware accounting) --- # adaptive precision: whole dollars once it's real money, cents when small. cost=$(awk "BEGIN{c=${cost_usd:-0}; if(c>=100) printf \"%.0f\",c; else if(c>=10) printf \"%.1f\",c; else printf \"%.2f\",c}") # --- rate limits (each % colored on the same thresholds, + reset countdown) --- _rl() { # $1=pct $2=label $3=reset_ts -> "