statuslin.es

Dreambase Flat

One-line adaptation of @kyleledbetter's Dreambase Panel: a context bar with status word, token/cost/duration/lines-changed stats, and model + git branch + clock, all on a single line in a terracotta Claude-brand palette.

Updated 2026-07-16

Preview

Clean repo
████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · main · 21:45
New session
░░░░░░░░░░░░░░░░░░░░░░ 0% of 200K · GOOD 0 0 $0.00 ⏱ 10m 12s Opus 4.8 · main · 21:45
Dirty branch
██████████▌░░░░░░░░░░░ 48% of 200K · GOOD 96.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Sonnet 4.6 · feat/auth ~1 ?1 · 21:45 I
Near-full
████████████████████░░ 91% of 200K · HIGH 182.0K 1.4K $4.12 ⏱ 10m 12s +128/-34 Opus 4.8 · main · 21:45
1M context
██████████████░░░░░░░░ 64% of 1M · OK 640.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Fable 5 · main · 21:45
Post-compact
░░░░░░░░░░░░░░░░░░░░░░ 0% of 200K · GOOD 0 0 $0.41 ⏱ 10m 12s +128/-34 Haiku 4.5 · main · 21:45 N
Worktree
████████▏░░░░░░░░░░░░░ 37% of 200K · GOOD 74.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · 21:45
Non-git
████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · 21:45

Source

#!/usr/bin/env python3
"""Claude Code Status Line — Dreambase Flat
   Single-line adaptation of @kyleledbetter's Dreambase Panel: the same
   context bar, stats, and repo sections in a terracotta Claude-brand
   palette, rendered on one line instead of a boxed three-row panel.
"""

import json
import os
import subprocess
import sys
import time

data = json.load(sys.stdin)

# ── Extract data ──────────────────────────────────────────
model = data.get("model", {}).get("display_name", "—")
model_id = data.get("model", {}).get("id", "")
project_dir = data.get("workspace", {}).get("project_dir", ".")
current_dir = data.get("workspace", {}).get("current_dir", ".")
pct = int(float(data.get("context_window", {}).get("used_percentage") or 0))
ctx_size = int(data.get("context_window", {}).get("context_window_size") or 200000)
input_tokens = int(data.get("context_window", {}).get("total_input_tokens") or 0)
output_tokens = int(data.get("context_window", {}).get("total_output_tokens") or 0)
cost_usd = float(data.get("cost", {}).get("total_cost_usd") or 0)
duration_ms = int(data.get("cost", {}).get("total_duration_ms") or 0)
lines_added = int(data.get("cost", {}).get("total_lines_added") or 0)
lines_removed = int(data.get("cost", {}).get("total_lines_removed") or 0)
exceeds_200k = data.get("exceeds_200k_tokens", False)
vim_mode = data.get("vim", {}).get("mode", "")

# ── ANSI Colors ───────────────────────────────────────────
R = "\033[0m"
B = "\033[1m"
D = "\033[2m"

# Claude brand rust / terracotta
RUST = "\033[38;5;173m"
RUST_B = "\033[38;5;209m"
RUST_D = "\033[38;5;131m"
RUST_BG = "\033[48;5;52m"

# Functional
GRN = "\033[38;5;34m"
LIME = "\033[38;5;118m"
YEL = "\033[38;5;220m"
ORG = "\033[38;5;208m"
RED = "\033[38;5;196m"
CYN = "\033[38;5;81m"
BLU = "\033[38;5;69m"
PUR = "\033[38;5;141m"
WHT = "\033[38;5;255m"
GRY = "\033[38;5;243m"

# ── Formatters ────────────────────────────────────────────
def fmt_tok(n):
    if n >= 1_000_000:
        return f"{n / 1_000_000:.1f}M"
    if n >= 1_000:
        return f"{n / 1_000:.1f}K"
    return str(n)


def fmt_dur(ms):
    s = ms // 1000
    h, rem = divmod(s, 3600)
    m, sec = divmod(rem, 60)
    if h:
        return f"{h}h {m}m"
    if m:
        return f"{m}m {sec}s"
    return f"{sec}s"


def truncate(s, maxlen=18):
    return s[: maxlen - 1] + "…" if len(s) > maxlen else s


# ── Progress bar ──────────────────────────────────────────
BAR_W = 22
BLOCKS = " ▏▎▍▌▋▊▉█"

if pct >= 95:
    bar_clr = RED
    status_label = f"{RED}{B}CRITICAL{R}"
elif pct >= 85:
    bar_clr = ORG
    status_label = f"{ORG}HIGH{R}"
elif pct >= 70:
    bar_clr = YEL
    status_label = f"{YEL}MODERATE{R}"
elif pct >= 50:
    bar_clr = LIME
    status_label = f"{LIME}OK{R}"
else:
    bar_clr = GRN
    status_label = f"{GRN}GOOD{R}"

eighths = pct * BAR_W * 8 // 100
full = eighths // 8
partial = eighths % 8
empty = BAR_W - full - (1 if partial else 0)

bar = "█" * full
if partial:
    bar += BLOCKS[partial]
bar += "░" * empty

ctx_label = "1M" if ctx_size >= 1_000_000 else "200K"
warn = f" {RED}{B}{R}" if exceeds_200k else ""

# ── Git info (cached for perf) ────────────────────────────
CACHE = "/tmp/claude-sl-git"


def git_info():
    try:
        if time.time() - os.path.getmtime(CACHE) < 5:
            with open(CACHE) as f:
                p = f.read().strip().split("|")
                if len(p) == 4:
                    return p
    except (OSError, ValueError):
        pass
    try:
        br = subprocess.run(
            ["git", "-C", project_dir, "branch", "--show-current"],
            capture_output=True, text=True, timeout=2,
        ).stdout.strip()
        if not br:
            return ["", "0", "0", "0"]
        st = len(subprocess.run(
            ["git", "-C", project_dir, "diff", "--cached", "--numstat"],
            capture_output=True, text=True, timeout=2,
        ).stdout.strip().splitlines())
        mo = len(subprocess.run(
            ["git", "-C", project_dir, "diff", "--numstat"],
            capture_output=True, text=True, timeout=2,
        ).stdout.strip().splitlines())
        ut = len(subprocess.run(
            ["git", "-C", project_dir, "ls-files", "--others", "--exclude-standard"],
            capture_output=True, text=True, timeout=2,
        ).stdout.strip().splitlines())
        result = [br, str(st), str(mo), str(ut)]
        with open(CACHE, "w") as f:
            f.write("|".join(result))
        return result
    except Exception:
        return ["", "0", "0", "0"]


branch, staged, modified, untracked = git_info()
staged, modified, untracked = int(staged), int(modified), int(untracked)

# ── Derived values ────────────────────────────────────────
in_t = fmt_tok(input_tokens)
out_t = fmt_tok(output_tokens)
cost_s = f"${cost_usd:.2f}"
dur_s = fmt_dur(duration_ms)
clock = time.strftime("%H:%M")

# Git indicators
git_ind = ""
if staged:
    git_ind += f" {GRN}+{staged}{R}"
if modified:
    git_ind += f" {YEL}~{modified}{R}"
if untracked:
    git_ind += f" {GRY}?{untracked}{R}"

# Lines changed
lines_s = ""
if lines_added or lines_removed:
    lines_s = f"{GRN}+{lines_added}{R}{D}/{R}{RED}-{lines_removed}{R}"

# Model diamond icon
if "opus" in model_id:
    m_icon = f"{RUST_B}{R}"
elif "sonnet" in model_id:
    m_icon = f"{BLU}{R}"
elif "haiku" in model_id:
    m_icon = f"{GRN}{R}"
else:
    m_icon = f"{GRY}{R}"

# Vim mode
vim_s = ""
if vim_mode == "NORMAL":
    vim_s = f" {RUST_BG}{WHT}{B} N {R}"
elif vim_mode == "INSERT":
    vim_s = f" {RUST_BG}{WHT}{B} I {R}"

# ── Build content strings ─────────────────────────────────
ctx_content = (
    f"{bar_clr}{bar}{R}  {WHT}{B}{pct}%{R}{warn}"
    f" {D}of{R} {RUST}{ctx_label}{R}  {D}·{R}  {status_label}"
)

stats_content = (
    f"{BLU}{R} {in_t}  {PUR}{R} {out_t}"
    f"  {RUST_D}{R}  {YEL}{cost_s}{R}"
    f"  {RUST_D}{R}  {GRY}{dur_s}{R}"
    + (f"  {RUST_D}{R}  {lines_s}" if lines_s else "")
)

repo_content = f"{m_icon} {RUST_B}{B}{model}{R}"
if branch:
    repo_content += f"  {RUST_D}·{R}  {PUR}{truncate(branch)}{R}{git_ind}"
repo_content += f"  {RUST_D}·{R}  {GRY}{clock}{R}"
repo_content += vim_s

# ── Render (single line) ──────────────────────────────────
sep = f"  {RUST}{R}  "
print(sep.join([ctx_content, stats_content, repo_content]))

What it shows

  • Context window usage as a percentage with a color-coded 22-character progress bar
  • A status word that changes from GOOD to OK, MODERATE, HIGH, or CRITICAL based on usage
  • The context window size as a 200K or 1M label
  • A warning symbol when Claude Code reports more than 200K tokens
  • Total input and output token counts in compact K or M notation
  • Total session cost in US dollars
  • Total session duration formatted as hours and minutes, minutes and seconds, or seconds alone
  • Lines of code added and removed during the session
  • The model display name with a diamond icon colored by model family
  • The current git branch and non-zero staged, modified, and untracked file counts
  • The current wall-clock time in HH:MM format
  • A highlighted N or I badge for Vim NORMAL or INSERT mode
  • All values appear on one line, separated by colored vertical bars

Requirements

  • Python 3 with only standard-library modules
  • Claude Code must provide its status JSON on standard input
  • The git command on PATH for branch and working-tree counts; git details are omitted when no branch is found
  • A terminal that supports 256-color ANSI escape codes
  • A terminal font that renders Unicode block, arrow, box-drawing, and symbol characters; no Nerd Font glyphs are required
  • Write access to /tmp for the five-second git info cache
  • No network access; the script makes no network calls

Behavior notes

  • The progress bar and status word follow context usage: 22% and 37% show GOOD, 64% shows OK, and 91% shows HIGH in the rendered scenarios
  • A warning symbol appears when exceeds_200k_tokens is true, as in the 91% and 1M-context scenarios
  • The context label changes from 200K to 1M when context_window_size reaches 1,000,000
  • The progress bar uses fractional block characters at values such as 22% and 37%
  • A fresh session treats missing usage as 0%, displays zero tokens and $0.00, and omits the lines-changed segment
  • Input and output totals, cost, duration, and line changes are formatted from session values, using K or M suffixes and compact duration units
  • The dirty feature branch adds ~1 modified and ?1 untracked indicators, while the non-git scenario omits branch and git counts
  • The model diamond is terracotta for Opus, blue for Sonnet, green for Haiku, and gray for other model IDs
  • The Vim badge appears only for NORMAL and INSERT modes; VISUAL and VISUAL LINE produce no badge
  • Branch labels longer than 18 characters are truncated with an ellipsis
  • Git info is reused from /tmp/claude-sl-git for five seconds between renders
  • The status line stays on one line and uses vertical separators instead of the bordered multi-row layout of the related panel

More status lines

app · main · Opus-4.8 · effort high · ctx 22% · 5h 26% ↻2h6m · 7d 7% ↻2d0h
app · main · OPUS-4.8 ▓▓░░░░░░ 22% · ▓▓░░░░░ 26% · ▓░░░░░░ 7%
Opus 4.8 ✍️ 22% app (main) ● high current ●●○○○○○○○○ 26% 8:49pm weekly ○○○○○○○○○○ 7% jul 8, 7:42pm
███████████▋ 73% 🗝 Ultima Weapon ✦ app ∙ main ████████████████████████ 100% 「SAVE POINT」 ✶ Limit Form ◉ 41
╭─ CONTEXT ────────────────────────────────────────────╮ ████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD ├─ STATS ──────────────────────────────────────────────┤ 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 ├─ REPO ───────────────────────────────────────────────┤ Opus 4.8 · main · 17:27 ╰──────────────────────────────────────────────────────╯
Opus 4.8 | main | ██░░░░░░░░ 22.0% | 44k / 200k | 02:07 26% | Wed 7%