Last active
February 16, 2026 22:56
-
-
Save terraboops/fa7b3307e6dcb8041fa6cadeb7cb3e3f to your computer and use it in GitHub Desktop.
0xSTATUS — a cute and nerdy statusline for Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # ╔════════════════════════════════════════════════════════════╗ | |
| # ║ 0xSTATUS v1.2 // cute and nerdy statusline for Claude ║ | |
| # ╚════════════════════════════════════════════════════════════╝ | |
| # | |
| # Requires: jq | |
| # Optional: kubectl (k8s context), git (branch) | |
| # Works with any modern monospace font (no Nerd Font required) | |
| # | |
| # Layout: | |
| # | |
| # ┌────────────────┬────────────────┬────────────────────┬─────────────────────────┐ | |
| # │ ⎈ k8s context │ ⌥ git branch │ working dir │ model ver ⌂ home │ | |
| # │ [====──] ctx% │ ▲ in ▼ out │ $1.20 ($3/h) +8 -2 │ ⏱ dur ⚡ cache ◈ api │ | |
| # └────────────────┴────────────────┴────────────────────┴─────────────────────────┘ | |
| # T1 T2 T3 T4 | |
| # | |
| # Line 1 — where you are: | |
| # T1 ⎈ k8s context Current kubectl context (cached 15s) | |
| # T2 ⌥ git branch Current branch name | |
| # T3 path Working directory (collapsed if deep) | |
| # T4 model + version Claude model ID, CLI version, config home | |
| # | |
| # Line 2 — how it's going: | |
| # T1 [━━──] % Context window usage bar + percentage | |
| # T2 ▲ / ▼ Total input / output tokens | |
| # T3 $ Cost, burn rate ($/hr), lines +added / -removed | |
| # T4 ⏱ duration Wall-clock time | |
| # ⚡ cache hit % cache_read / total_cache tokens | |
| # ◈ API efficiency % api_duration / wall_clock | |
| # ── Guard ────────────────────────────────────────────────── | |
| command -v jq &>/dev/null || { echo "0xERR: jq not found"; exit 0; } | |
| # ── Ingest ───────────────────────────────────────────────── | |
| INPUT=$(cat) | |
| if [[ -z "$INPUT" ]]; then | |
| echo "0xSTATUS: awaiting uplink…" | |
| exit 0 | |
| fi | |
| # ── Palette (truecolor) ─────────────────────────────────── | |
| R=$'\033[0m' | |
| B=$'\033[1m' | |
| D=$'\033[2m' | |
| GRN=$'\033[38;2;57;255;20m' # acid green | |
| CYN=$'\033[38;2;0;230;255m' # electric cyan | |
| MAG=$'\033[38;2;220;130;255m' # bright lilac | |
| PNK=$'\033[38;2;255;100;180m' # bright pink | |
| YLW=$'\033[38;2;255;230;0m' # amber | |
| RED=$'\033[38;2;255;50;50m' # red alert | |
| WHT=$'\033[38;2;240;240;255m' # bright white | |
| GRY=$'\033[38;2;160;160;190m' # bright silver | |
| BLU=$'\033[38;2;80;160;255m' # soft blue | |
| # ── Extract (single jq call for speed) ──────────────────── | |
| IFS=$'\t' read -r MODEL VER CWD_RAW CTX_PCT TOT_IN TOT_OUT \ | |
| C_READ C_WRITE COST DUR_MS API_MS L_ADD L_REM <<< \ | |
| "$(echo "$INPUT" | jq -r '[ | |
| (.model.id // "?"), | |
| (.version // "?"), | |
| (.cwd // "."), | |
| (.context_window.used_percentage // 0), | |
| (.context_window.total_input_tokens // 0), | |
| (.context_window.total_output_tokens // 0), | |
| (.context_window.current_usage.cache_read_input_tokens // 0), | |
| (.context_window.current_usage.cache_creation_input_tokens // 0), | |
| (.cost.total_cost_usd // 0), | |
| (.cost.total_duration_ms // 0), | |
| (.cost.total_api_duration_ms // 0), | |
| (.cost.total_lines_added // 0), | |
| (.cost.total_lines_removed // 0) | |
| ] | @tsv')" | |
| # ── Helpers: formatting ────────────────────────────────── | |
| ftk() { | |
| local n=${1%.*} | |
| n=${n:-0} | |
| if ((n >= 1000000)); then | |
| awk "BEGIN{printf \"%.1fM\", $n / 1e6}" | |
| elif ((n >= 1000)); then | |
| awk "BEGIN{printf \"%.1fk\", $n / 1e3}" | |
| else | |
| printf "%d" "$n" | |
| fi | |
| } | |
| fdur() { | |
| local total_sec=$(( ${1%.*} / 1000 )) | |
| total_sec=${total_sec:-0} | |
| local h=$((total_sec / 3600)) | |
| local m=$(((total_sec % 3600) / 60)) | |
| local s=$((total_sec % 60)) | |
| if ((h > 0)); then | |
| printf "%dh%02dm" "$h" "$m" | |
| elif ((m > 0)); then | |
| printf "%dm%02ds" "$m" "$s" | |
| else | |
| printf "%ds" "$s" | |
| fi | |
| } | |
| spath() { | |
| local p="${1/#$HOME/~}" | |
| local depth | |
| depth=$(printf '%s' "$p" | awk -F/ '{print NF}') | |
| if ((depth > 4)); then | |
| local head tail | |
| head=$(echo "$p" | cut -d/ -f1-2) | |
| tail=$(echo "$p" | rev | cut -d/ -f1-2 | rev) | |
| printf "%s/…/%s" "$head" "$tail" | |
| else | |
| printf '%s' "$p" | |
| fi | |
| } | |
| trunc() { | |
| local s="$1" | |
| local max=${2:-25} | |
| if ((${#s} > max)); then | |
| printf "%s…" "${s:0:$((max - 1))}" | |
| else | |
| printf "%s" "$s" | |
| fi | |
| } | |
| # ── Helpers: sanitization ──────────────────────────────── | |
| to_int() { | |
| local v=${1%.*} | |
| v=${v:-0} | |
| if [[ "$v" =~ ^-?[0-9]+$ ]]; then | |
| printf "%d" "$v" | |
| else | |
| printf "0" | |
| fi | |
| } | |
| ratio() { | |
| local num=$1 den=$2 fmt=$3 fallback=${4:-"---"} | |
| if ((den > 0)); then | |
| awk "BEGIN{printf \"$fmt\", $num / $den * 100}" | |
| else | |
| printf "%s" "$fallback" | |
| fi | |
| } | |
| # ── Helpers: cache ─────────────────────────────────────── | |
| CACHE_DIR="/tmp/.0xstatus-${UID:-$(id -u)}" | |
| mkdir -p "$CACHE_DIR" 2>/dev/null | |
| file_mtime() { | |
| stat -f %m "$1" 2>/dev/null || stat -c %Y "$1" 2>/dev/null || echo 0 | |
| } | |
| cache_read() { | |
| local file="$1" | |
| local ttl_sec=$2 | |
| if [[ ! -f "$file" ]]; then | |
| return 1 | |
| fi | |
| local mtime now age | |
| mtime=$(file_mtime "$file") | |
| now=$(date +%s) | |
| age=$((now - mtime)) | |
| if ((age < 0 || age >= ttl_sec)); then | |
| return 1 | |
| fi | |
| cat "$file" 2>/dev/null | |
| } | |
| cache_write() { | |
| local file="$1" | |
| local value="$2" | |
| printf "%s" "$value" > "$file" 2>/dev/null | |
| } | |
| # ── Helpers: tile rendering ──────────────────────────────── | |
| # Both rows share these column widths so separators align vertically. | |
| # All 4 columns are padded to fixed widths for alignment. | |
| COLS=(24 24 26 34) | |
| # Visible width of a string (strips ANSI escape codes) | |
| vwidth() { | |
| local stripped | |
| stripped=$(printf '%s' "$1" | sed $'s/\033\\[[0-9;]*m//g') | |
| echo "${#stripped}" | |
| } | |
| # Right-pad content to target visible width | |
| tile() { | |
| local content="$1" width=$2 | |
| local vw pad | |
| vw=$(vwidth "$content") | |
| pad=$((width - vw)) | |
| if ((pad > 0)); then | |
| printf '%s%*s' "$content" "$pad" "" | |
| else | |
| printf '%s' "$content" | |
| fi | |
| } | |
| # ── Computed Metrics ────────────────────────────────────── | |
| CTX=$(to_int "$CTX_PCT") | |
| DI=$(to_int "$DUR_MS") | |
| AI=$(to_int "$API_MS") | |
| CR=$(to_int "$C_READ") | |
| CW=$(to_int "$C_WRITE") | |
| # Context bar color | |
| if ((CTX >= 80)); then | |
| BC=$RED | |
| elif ((CTX >= 60)); then | |
| BC=$YLW | |
| else | |
| BC=$GRN | |
| fi | |
| # Progress bar [▓▓▓▓▓░░░░░] | |
| FL=$((CTX / 10)) | |
| EM=$((10 - FL)) | |
| BAR="${BC}" | |
| for ((i = 0; i < FL; i++)); do BAR+="━"; done | |
| BAR+="${GRY}" | |
| for ((i = 0; i < EM; i++)); do BAR+="─"; done | |
| BAR+="${R}" | |
| # Burn rate ($/hr) -- need >1min of data for meaningful rate | |
| if ((DI > 60000)); then | |
| BURN=$(awk "BEGIN{printf \"\$%.2f/h\", $COST / $DI * 3.6e6}") | |
| else | |
| BURN="---" | |
| fi | |
| # Cache hit ratio | |
| CT=$((CR + CW)) | |
| CPCT=$(ratio "$CR" "$CT" "%.0f%%") | |
| # API efficiency (% of wall-clock spent in API) | |
| AEFF=$(ratio "$AI" "$DI" "%.0f%%") | |
| # ── External Data ──────────────────────────────────────── | |
| sep() { | |
| printf "${PNK} ✧ ${R}" | |
| } | |
| # k8s context (15s TTL cache) | |
| K8S_FILE="${CACHE_DIR}/k8s" | |
| K8S=$(cache_read "$K8S_FILE" 15) | |
| if [[ -z "$K8S" ]]; then | |
| K8S=$(kubectl config current-context 2>/dev/null || echo "---") | |
| cache_write "$K8S_FILE" "$K8S" | |
| fi | |
| # Git branch | |
| GIT=$(git -C "$CWD_RAW" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "---") | |
| # Claude home (from CLAUDE_CONFIG_DIR env var) | |
| if [[ -n "$CLAUDE_CONFIG_DIR" ]]; then | |
| CHOME="${CLAUDE_CONFIG_DIR##*/}" # .claude-personal → .claude-personal | |
| CHOME="${CHOME#.claude-}" # .claude-personal → personal | |
| CHOME="${CHOME#.claude}" # .claude → "" (bare) | |
| CHOME="${CHOME:-default}" | |
| else | |
| CHOME="default" | |
| fi | |
| # ── Format Values ───────────────────────────────────────── | |
| F_IN=$(ftk "$TOT_IN") | |
| F_OUT=$(ftk "$TOT_OUT") | |
| F_COST=$(printf '$%.2f' "${COST:-0}") | |
| F_DUR=$(fdur "${DUR_MS:-0}") | |
| F_PATH=$(trunc "$(spath "$CWD_RAW")" 26) | |
| F_K8S=$(trunc "$K8S" 20) | |
| F_GIT=$(trunc "$GIT" 22) | |
| # ── Render ───────────────────────────────────────────────── | |
| # Build tile content (colored strings, not yet padded) | |
| # Line 1: 4 tiles — where you are | |
| T1_L1=$(printf "${CYN}⎈ ${B}%s${R}" "$F_K8S") | |
| T2_L1=$(printf "${GRN}⌥ ${B}%s${R}" "$F_GIT") | |
| T3_L1=$(printf "${MAG}%s${R}" "$F_PATH") | |
| if [[ "$CHOME" != "default" ]]; then | |
| T4_L1=$(printf "${PNK}${B}%s${R} ${GRY}v%s${R} ${YLW}⌂ ${WHT}%s${R}" "$MODEL" "$VER" "$CHOME") | |
| else | |
| T4_L1=$(printf "${PNK}${B}%s${R} ${GRY}v%s${R}" "$MODEL" "$VER") | |
| fi | |
| # Line 2: 4 tiles — how it's going | |
| T1_L2=$(printf "${BC}${B}[${R}%s${BC}${B}] %s%%${R}" "$BAR" "$CTX") | |
| T2_L2=$(printf "${CYN}▲ ${WHT}%s ${CYN}▼ ${WHT}%s${R}" "$F_IN" "$F_OUT") | |
| T3_L2=$(printf "${GRN}${B}%s${R} ${GRY}(%s)${R} ${GRN}+%s${R} ${RED}-%s${R}" "$F_COST" "$BURN" "$L_ADD" "$L_REM") | |
| T4_L2=$(printf "${BLU}⏱ ${WHT}%s${R} ${YLW}⚡ ${WHT}%s${R} ${MAG}◈ ${WHT}%s${R}" "$F_DUR" "$CPCT" "$AEFF") | |
| # Blank line for visual separation from Claude's interface | |
| echo | |
| # Line 1 (first tile -2 to compensate for ◆ and ⎈ double-width rendering) | |
| printf "${GRN}◆${R} " | |
| tile "$T1_L1" "$((COLS[0] - 2))"; sep 0 | |
| tile "$T2_L1" "${COLS[1]}"; sep 1 | |
| tile "$T3_L1" "${COLS[2]}"; sep 2 | |
| tile "$T4_L1" "${COLS[3]}" | |
| echo | |
| # Line 2 (5-space indent: ◆ + ⎈ each render as 2 cells in Claude Code's terminal) | |
| printf " " | |
| tile "$T1_L2" "${COLS[0]}"; sep | |
| tile "$T2_L2" "${COLS[1]}"; sep | |
| tile "$T3_L2" "${COLS[2]}"; sep | |
| tile "$T4_L2" "${COLS[3]}" | |
| printf "\n${R}\n" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment