#!/usr/bin/env python3 """ Claude Code Status Line — comprehensive, beautiful, Windows-compatible. Displays: 1. Current model name 2. Context token usage (used/max/remaining, percentage, visual progress bar) 3. Current agent/skill being invoked 4. Total loaded skills count 5. Git branch (bonus) 6. Session cost & duration (bonus) Input: JSON from Claude Code via stdin Output: Single-line formatted status string """
import json import os import subprocess import sys from pathlib import Path
# ---------- Windows encoding setup ---------- if sys.platform == "win32": sys.stdout.reconfigure(encoding="utf-8", errors="replace") sys.stdin.reconfigure(encoding="utf-8", errors="replace")
# ---------- helpers ----------
defget_key(d, *keys, default=None): """Safe nested dict access.""" for k in keys: ifisinstance(d, dict): d = d.get(k) else: return default return d if d isnotNoneelse default
defcolor(text: str, code: str) -> str: """Apply ANSI color if terminal.""" ifhasattr(sys.stdout, "isatty") and sys.stdout.isatty(): reset = "\033[0m" returnf"{code}{text}{reset}" return text
# ANSI codes BOLD = "\033[1m" DIM = "\033[2m"
# Colors (foreground) CYAN = "\033[36m" GREEN = "\033[32m" YELLOW = "\033[33m" RED = "\033[31m" MAGENTA = "\033[35m" BLUE = "\033[34m"
# ---------- progress bar ----------
defprogress_bar(percentage: float, width: int = 10) -> str: """Build a color-coded Unicode progress bar. Width 10: each cell = 10%. Uses eighths for partial fill. """ pct = max(0.0, min(100.0, percentage)) full_blocks = int(pct / (100.0 / width)) remainder = pct / (100.0 / width) - full_blocks
# Color by usage level if pct < 50: bar_color = GREEN elif pct < 80: bar_color = YELLOW else: bar_color = RED
filled = color("█" * full_blocks, bar_color) part = color(partial, bar_color) if partial else"" empty = color("·" * max(0, empty_blocks), DIM)
returnf"{filled}{part}{empty}"
# ---------- git ----------
defget_git_branch(cwd: str) -> str: """Get current git branch name.""" try: result = subprocess.run( ["git", "--no-optional-locks", "-C", cwd, "symbolic-ref", "--short", "HEAD"], capture_output=True, text=True, timeout=2, creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32"else0, ) if result.returncode == 0: return result.stdout.strip() except Exception: pass return""
# ---------- skills count ----------
defcount_skills() -> int: """Count skill directories in the user's skills folder.""" skills_dir = Path.home() / ".claude" / "skills" ifnot skills_dir.is_dir(): return0 count = 0 try: for entry in skills_dir.iterdir(): if entry.is_dir() and (entry / "SKILL.md").exists(): count += 1 except OSError: pass return count
# ---------- format helpers ----------
deffmt_tokens(n: int) -> str: """Format token count in human-readable form.""" if n >= 1_000_000: returnf"{n / 1_000_000:.1f}M" if n >= 1_000: returnf"{n / 1_000:.1f}k" returnstr(n)
deffmt_duration(ms: int) -> str: """Format milliseconds to human-readable duration.""" if ms < 1000: returnf"{ms}ms" if ms < 60_000: returnf"{ms / 1000:.0f}s" mins = ms // 60_000 secs = (ms % 60_000) // 1000 returnf"{mins}m{secs}s"
deffmt_cost(usd: float) -> str: """Format USD cost.""" if usd < 0.01: returnf"${usd:.4f}" if usd < 1: returnf"${usd:.2f}" returnf"${usd:.2f}"
# ---------- main ----------
defmain(): try: data = json.load(sys.stdin) except (json.JSONDecodeError, Exception): print(" Claude Code") return