statuslin.es

Cost Thresholds

Directory, Node version when a package.json is around, added and removed lines with a net-direction arrow, a token bar, and a session cost that changes color as it grows.

MIT licensed · original source

Updated 2026-07-06

0 copies

Preview

Clean repo
app ⏱ 10m +128 -34 ░░░░░░░ 22% $0.41 ◆ Opus
New session
app ⏱ 10m $0.00 ◆ Opus
Dirty branch
app ⏱ 10m +128 -34 ▓▓▓░░░░░ 48% $0.41 ◇ Sonnet
Near-full
app ⏱ 10m +128 -34 ▓▓▓▓▓▓▓ 91% $4.12 ◆ Opus
1M context
app ⏱ 10m +128 -34 ▓▓▓▓▓░░░ 64% $0.41 ● Fable 5
Post-compact
app ⏱ 10m +128 -34 $0.41 ○ Haiku
Worktree
feature ⏱ 10m +128 -34 ▓▓░░░░░░ 37% $0.41 ◆ Opus
Non-git
scratch ⏱ 10m +128 -34 ░░░░░░░ 22% $0.41 ◆ Opus

Source

#!/bin/bash
export TERM=xterm-256color
input=$(cat)
cwd=$(echo "$input" | jq -r '.workspace.current_dir')
model=$(echo "$input" | jq -r '.model.display_name // empty')

# Token usage
input_tokens=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0')
output_tokens=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0')
context_limit=$(echo "$input" | jq -r '.context_window.context_window_size // 0')
total_tokens=$((input_tokens + output_tokens))

# Cost & stats
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
duration_ms=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
lines_added=$(echo "$input" | jq -r '.cost.total_lines_added // 0')
lines_removed=$(echo "$input" | jq -r '.cost.total_lines_removed // 0')

# Colors - basic ANSI codes compatible with most terminals
RED=$'\033[31m'
GREEN=$'\033[32m'
YELLOW=$'\033[33m'
BLUE=$'\033[34m'
MAGENTA=$'\033[35m'
CYAN=$'\033[36m'
GRAY=$'\033[90m'
RESET=$'\033[0m'

SEP="${GRAY}${RESET}"
short_dir=$(basename "$cwd")

# Node version (only if package.json exists)
node_info=""
if [ -f "$cwd/package.json" ] 2>/dev/null; then
  node_ver=$(node -v 2>/dev/null | sed 's/v//')
  [ -n "$node_ver" ] && node_info=" ${SEP} ${GREEN}⬢ ${node_ver}${RESET}"
fi

# Session duration
duration_info=""
if [ "$duration_ms" -gt 0 ] 2>/dev/null; then
  duration_sec=$((duration_ms / 1000))
  if [ "$duration_sec" -ge 3600 ]; then
    hours=$((duration_sec / 3600))
    mins=$(((duration_sec % 3600) / 60))
    duration_fmt="${hours}h${mins}m"
  elif [ "$duration_sec" -ge 60 ]; then
    mins=$((duration_sec / 60))
    duration_fmt="${mins}m"
  else
    duration_fmt="${duration_sec}s"
  fi
  duration_info=" ${SEP} ${CYAN}⏱ ${duration_fmt}${RESET}"
fi

# Lines changed
lines_info=""
if [ "$lines_added" -gt 0 ] || [ "$lines_removed" -gt 0 ] 2>/dev/null; then
  net=$((lines_added - lines_removed))
  if [ "$net" -gt 0 ]; then
    net_symbol="${GREEN}▲${RESET}"
  elif [ "$net" -lt 0 ]; then
    net_symbol="${RED}▼${RESET}"
  else
    net_symbol="${GRAY}=${RESET}"
  fi
  lines_info=" ${SEP} ${net_symbol} ${GREEN}+${lines_added}${RESET} ${RED}-${lines_removed}${RESET}"
fi

# Token usage with progress bar
token_info=""
if [ "$total_tokens" -gt 0 ] 2>/dev/null; then
  if [ "$total_tokens" -ge 1000 ]; then
    tokens_fmt="$((total_tokens / 1000))k"
  else
    tokens_fmt="$total_tokens"
  fi

  if [ "$context_limit" -gt 0 ] 2>/dev/null; then
    pct=$((total_tokens * 100 / context_limit))

    # Color based on usage
    if [ "$pct" -ge 75 ]; then
      bar_color="$RED"
    elif [ "$pct" -ge 50 ]; then
      bar_color="$YELLOW"
    else
      bar_color="$GREEN"
    fi

    # Build progress bar using simple chars: ▓ filled, ░ empty
    bar_width=8
    filled=$((pct * bar_width / 100))
    [ "$filled" -gt "$bar_width" ] && filled=$bar_width
    [ "$filled" -lt 1 ] && [ "$pct" -gt 0 ] && filled=1
    empty=$((bar_width - filled))

    bar="${bar_color}"
    for ((i=0; i<filled; i++)); do bar+="▓"; done
    bar+="${GRAY}"
    for ((i=0; i<empty; i++)); do bar+="░"; done
    bar+="${RESET}"

    token_info=" ${SEP} ${bar} ${GRAY}${pct}%${RESET}"
  fi
fi

# Cost with meaningful colors
cost_info=""
if [ -n "$cost" ] && [ "$cost" != "null" ]; then
  cost_fmt=$(printf "%.2f" "$cost")
  cost_cents=$(printf "%.0f" "$(echo "$cost * 100" | bc)")

  if [ "$cost_cents" -ge 1000 ] 2>/dev/null; then
    cost_color="$RED"
  elif [ "$cost_cents" -ge 200 ] 2>/dev/null; then
    cost_color="$YELLOW"
  else
    cost_color="$GREEN"
  fi
  cost_info=" ${SEP} ${cost_color}\$${cost_fmt}${RESET}"
fi

# Model with tier colors
model_info=""
if [ -n "$model" ]; then
  case "$model" in
    *Opus*) model_color="$MAGENTA"; model_symbol="◆"; short_model="Opus" ;;
    *Sonnet*) model_color="$BLUE"; model_symbol="◇"; short_model="Sonnet" ;;
    *Haiku*) model_color="$GREEN"; model_symbol="○"; short_model="Haiku" ;;
    *) model_color="$GRAY"; model_symbol="●"; short_model="$model" ;;
  esac
  model_info=" ${SEP} ${model_color}${model_symbol} ${short_model}${RESET}"
fi

printf "${BLUE}${short_dir}${RESET}%s%s%s%s%s%s" "$node_info" "$duration_info" "$lines_info" "$token_info" "$cost_info" "$model_info"

What it shows

  • Current directory name (basename of the working directory)
  • Node.js version, shown only when a package.json exists in the current directory
  • Session duration, formatted as seconds, minutes, or hours and minutes
  • Lines added and removed in the session, with a net-direction symbol (up arrow, down arrow, or equals sign)
  • Context window usage as an 8-character progress bar plus a percentage
  • Total session cost in US dollars, rounded to cents
  • Model name shortened to its tier (Opus, Sonnet, Haiku) with a tier-specific symbol and color, or the full display name for other models

Requirements

  • Bash
  • jq for parsing the JSON that Claude Code sends on stdin
  • bc for converting the cost to cents
  • node on the PATH if you want the Node version segment; the segment is silently skipped when node is missing
  • A terminal that renders basic ANSI colors and Unicode symbols (▓ ░ ▲ ▼ ⏱ ⬢ ◆ ◇ ○ ●); no Nerd Font needed
  • No network access

Behavior notes

  • In a brand-new session with zero tokens and zero changed lines, the token bar and the lines segment disappear entirely, leaving directory, duration, cost, and model
  • A cost of exactly zero still renders, as a green $0.00
  • The progress bar and percentage change color with usage: green below 50% (22%, 37%), yellow from 50% (64%), red from 75% (91%)
  • The cost changes color as it grows: green below $2 ($0.41), yellow from $2 ($4.12), red from $10
  • The percentage is computed against the session's actual context window size, so a 1M-token window shows 64% rather than overflowing
  • Model matching is by display-name substring: Opus, Sonnet, and Haiku get their own colors and symbols, while Fable 5 falls through to the gray default and keeps its full name
  • In a git worktree the directory segment is just the basename of the current directory (feature), not the branch or project name
  • The Node version segment never appears in the rendered previews because none of the sandbox directories contained a package.json
  • Vim mode, rate limits, PR state, effort level, and git branch are present in the input JSON but have no effect on the output

More status lines

Dreambase Panel

150 copies

╭─ CONTEXT ────────────────────────────────────────────╮ ████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD ├─ STATS ──────────────────────────────────────────────┤ 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 ├─ REPO ───────────────────────────────────────────────┤ Opus 4.8 · main · 16:21 ╰──────────────────────────────────────────────────────╯
app · main · Opus-4.8 · effort high · ctx 22% · 5h 26% ↻2h6m · 7d 7% ↻2d0h
Opus 4.8 [high] ~/app main 16:20:55 | ⛁ ██░░░░░░░░ 22% | 5h ●◔○○○ 26% ↻2h7m | 7d ◔○○○○○○ 7% ↻2d1h │ $0.41 ⏱ 10m
Opus 4.8 main app 44k/200k $0.41

Activity Feed

36 copies

Opus 4.8 high ctx 22% app (main) PR #1287 $0.41 · 10m +128 -34 Session 74% left Resets in 2h 6m Weekly 93% left Resets in 2d 0h Fable 85% left Resets in 2d 0h ◐ Read:index.ts ✓ Read×1 ✓ Bash×1 ✓ Edit×1 ✓ Grep×1 ◐ code-reviewer Review the change for regressions
████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · main · 16:22