#!/usr/bin/env bash # Claude Code statusline. Layout: # [๐Ÿ“ฌN] [๐Ÿ””/๐Ÿ”•/๐Ÿ“ต] | โއ * โ†‘ | | ctx: | $ | 5h:% 7d:% # # ๐Ÿ”” reachable โ€” the post office will push to this session # ๐Ÿ”• pull-only โ€” nothing will poke it; mail waits until it looks # ๐Ÿ“ต the post office could not be asked โ€” an OUTAGE, not an empty inbox # 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 -> "