statuslin.es

Three-Line Cockpit

Model, context, lines changed and branch on the first line; a context bar with token counts on the second; session cost on the third. No network calls, just stdin and local git.

MIT licensed ยท original source

Updated 2026-07-06

1 copy

Preview

Clean repo
๐Ÿค– Opus 4.8 โ”‚ ๐Ÿ“Š 22% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ main ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 22% 44K / 200K tokens ๐Ÿ’ฐ $0.41
New session
๐Ÿค– Opus 4.8 โ”‚ ๐Ÿ“Š 0% โ”‚ ๐Ÿ”€ main ๐Ÿ“ CTX โ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 0% 0 / 200K tokens ๐Ÿ’ฐ --
Dirty branch
๐Ÿค– Sonnet 4.6 โ”‚ ๐Ÿ“Š 48% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ feat/auth ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 48% 96K / 200K tokens ๐Ÿ’ฐ $0.41
Near-full
๐Ÿค– Opus 4.8 โ”‚ ๐Ÿ“Š 91% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ main ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฑ 91% 182K / 200K tokens ๐Ÿ’ฐ $4.12
1M context
๐Ÿค– Fable 5 โ”‚ ๐Ÿ“Š 64% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ main ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑ 64% 640K / 1M tokens ๐Ÿ’ฐ $0.41
Post-compact
๐Ÿค– Haiku 4.5 โ”‚ ๐Ÿ“Š 0% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ main ๐Ÿ“ CTX โ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 0% 0 / 200K tokens ๐Ÿ’ฐ $0.41
Worktree
๐Ÿค– Opus 4.8 โ”‚ ๐Ÿ“Š 37% โ”‚ โœ๏ธ +128/-34 โ”‚ ๐Ÿ”€ worktree-feature ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 37% 74K / 200K tokens ๐Ÿ’ฐ $0.41
Non-git
๐Ÿค– Opus 4.8 โ”‚ ๐Ÿ“Š 22% โ”‚ โœ๏ธ +128/-34 ๐Ÿ“ CTX โ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ 22% 44K / 200K tokens ๐Ÿ’ฐ $0.41

Source

#!/bin/bash
# Claude Code statusline script (ToS-safe version)
# Line 1: Model | Context% | +added/-removed | git branch
# Line 2: Context window progress bar (detailed)
# Line 3: Session cost | Version
#
# This version uses ONLY stdin data provided by Claude Code.
# No external API calls, no OAuth token extraction, no keychain access.
# Fully compliant with Anthropic Consumer Terms of Service.

set -euo pipefail

# ---------- Read stdin (Claude Code provides JSON) ----------
input=$(cat)

# ---------- ANSI Colors ----------
readonly GREEN=$'\e[38;2;151;201;195m'
readonly YELLOW=$'\e[38;2;229;192;123m'
readonly RED=$'\e[38;2;224;108;117m'
readonly GRAY=$'\e[38;2;74;88;92m'
readonly RESET=$'\e[0m'
readonly DIM=$'\e[2m'

# ---------- Color by percentage ----------
color_for_pct() {
  local pct="${1:-0}"
  if [[ -z "$pct" || "$pct" == "null" ]]; then
    printf '%s' "$GRAY"
    return
  fi
  local ipct
  ipct=$(printf "%.0f" "$pct" 2>/dev/null) || ipct=0
  if (( ipct >= 80 )); then
    printf '%s' "$RED"
  elif (( ipct >= 50 )); then
    printf '%s' "$YELLOW"
  else
    printf '%s' "$GREEN"
  fi
}

# ---------- Progress bar (10 segments) ----------
progress_bar() {
  local pct="${1:-0}"
  local filled
  filled=$(awk "BEGIN{v=int($pct / 10 + 0.5); if(v>10)v=10; if(v<0)v=0; printf \"%d\", v}" 2>/dev/null) || filled=0
  local bar=""
  local i
  for (( i=1; i<=10; i++ )); do
    if (( i <= filled )); then
      bar+="โ–ฐ"
    else
      bar+="โ–ฑ"
    fi
  done
  printf '%s' "$bar"
}

# ---------- Safe JSON parsing (no eval) ----------
parse_json() {
  local json="$1"
  local query="$2"
  local default="${3:-}"
  local result
  result=$(printf '%s' "$json" | jq -r "$query" 2>/dev/null) || result=""
  if [[ -z "$result" || "$result" == "null" ]]; then
    printf '%s' "$default"
  else
    printf '%s' "$result"
  fi
}

# ---------- Parse stdin fields ----------
model_name=$(parse_json "$input" '.model.display_name // empty' 'Unknown')
used_pct=$(parse_json "$input" '.context_window.used_percentage // 0' '0')
remaining_pct=$(parse_json "$input" '.context_window.remaining_percentage // 100' '100')
ctx_size=$(parse_json "$input" '.context_window.context_window_size // 0' '0')
cwd=$(parse_json "$input" '.cwd // empty' '')
lines_added=$(parse_json "$input" '.cost.total_lines_added // 0' '0')
lines_removed=$(parse_json "$input" '.cost.total_lines_removed // 0' '0')
total_cost=$(parse_json "$input" '.cost.total_cost_usd // 0' '0')

# ---------- Git branch ----------
git_branch=""
if [[ -n "$cwd" && -d "$cwd" ]]; then
  git_branch=$(git -C "$cwd" --no-optional-locks rev-parse --abbrev-ref HEAD 2>/dev/null) || true
fi

# ---------- Line stats ----------
git_stats=""
if (( ${lines_added:-0} > 0 )) 2>/dev/null || (( ${lines_removed:-0} > 0 )) 2>/dev/null; then
  git_stats="+${lines_added}/-${lines_removed}"
fi

# ---------- Context window formatting ----------
ctx_pct_int=$(printf "%.0f" "${used_pct:-0}" 2>/dev/null) || ctx_pct_int=0

# Format context size (e.g., 200000 -> 200K)
format_tokens() {
  local tokens="${1:-0}"
  if (( tokens >= 1000000 )); then
    awk "BEGIN{printf \"%.0fM\", $tokens / 1000000}"
  elif (( tokens >= 1000 )); then
    awk "BEGIN{printf \"%.0fK\", $tokens / 1000}"
  else
    printf '%s' "$tokens"
  fi
}

ctx_size_display=$(format_tokens "$ctx_size")

# Used tokens (approximate)
used_tokens=0
if (( ctx_size > 0 )); then
  used_tokens=$(awk "BEGIN{printf \"%.0f\", $ctx_size * $used_pct / 100}" 2>/dev/null) || used_tokens=0
fi
used_tokens_display=$(format_tokens "$used_tokens")

# ---------- Cost formatting ----------
cost_display=""
if [[ -n "$total_cost" && "$total_cost" != "0" ]]; then
  cost_display=$(awk "BEGIN{printf \"\$%.2f\", $total_cost}" 2>/dev/null) || cost_display=""
fi

# ---------- Separator ----------
SEP="${GRAY} โ”‚ ${RESET}"

# ========== Line 1: Model | Context% | Changes | Branch ==========
ctx_color=$(color_for_pct "$ctx_pct_int")

line1="๐Ÿค– ${model_name}${SEP}${ctx_color}๐Ÿ“Š ${ctx_pct_int}%${RESET}"

if [[ -n "$git_stats" ]]; then
  line1+="${SEP}โœ๏ธ  ${GREEN}${git_stats}${RESET}"
fi

if [[ -n "$git_branch" ]]; then
  line1+="${SEP}๐Ÿ”€ ${git_branch}"
fi

# ========== Line 2: Context window progress bar ==========
ctx_bar_color=$(color_for_pct "$ctx_pct_int")
ctx_bar=$(progress_bar "$ctx_pct_int")

line2="${ctx_bar_color}๐Ÿ“ CTX  ${ctx_bar}  ${ctx_pct_int}%${RESET}"
if (( ctx_size > 0 )); then
  line2+="  ${DIM}${used_tokens_display} / ${ctx_size_display} tokens${RESET}"
fi

# ========== Line 3: Session cost ==========
line3=""
if [[ -n "$cost_display" ]]; then
  line3="${GREEN}๐Ÿ’ฐ ${cost_display}${RESET}"
else
  line3="${DIM}๐Ÿ’ฐ --${RESET}"
fi

# ---------- Output ----------
printf '%s\n' "$line1"
printf '%s\n' "$line2"
printf '%s' "$line3"

What it shows

  • Model display name
  • Context window usage as a percentage
  • Total lines added and removed in the session (+added/-removed)
  • Current git branch of the working directory
  • A 10-segment context window progress bar
  • Approximate used tokens and total context window size (e.g. 44K / 200K tokens)
  • Total session cost in US dollars

Requirements

  • Bash
  • jq, which the script uses for all JSON parsing
  • git, used to read the current branch
  • awk, used for rounding, token math, and cost formatting
  • A terminal that supports 24-bit ANSI color escape codes
  • A font that renders emoji (๐Ÿค– ๐Ÿ“Š โœ๏ธ ๐Ÿ”€ ๐Ÿ“ ๐Ÿ’ฐ) and the โ–ฐ/โ–ฑ bar characters
  • No network access; the script reads only stdin and the local git repository

Behavior notes

  • The context percentage and bar are green below 50%, yellow from 50% to 79%, and red at 80% or above (48% renders green, 64% yellow, 91% red).
  • The +added/-removed segment disappears when both line counts are zero, as in the brand-new session scenario.
  • The git branch segment disappears when the working directory is not a git repository, as in the scratch-directory scenario.
  • When used_percentage is null (brand-new session and just-after-/compact scenarios), the script falls back to 0%, an empty bar, and a 0-token count.
  • When total cost is zero, line 3 shows a dim '๐Ÿ’ฐ --' instead of a dollar amount.
  • Token counts are shortened with K and M suffixes; the 1M-context scenario renders as 640K / 1M tokens.
  • The used-token figure is computed from the context window size times the used percentage, not from the input-token fields in the JSON.
  • The branch name comes from running git in the session's cwd, not from the JSON, so the worktree scenario shows the worktree's actual branch (worktree-feature).
  • Fields such as rate limits, vim mode, effort level, PR info, and output style vary across the scenarios but never appear in 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