Skip to content

Commit 8e777ff

Browse files
committed
feat(claude): enrich statusline with resets and diffs
- Append rate-limit reset countdowns next to 5h/7d bars - Show effort level after model name (e.g. Opus·xhigh) - Display session lines added/removed in git-diff colors - Shrink bar width to 6 so the line fits in vsplit panes
1 parent 8c14d49 commit 8e777ff

1 file changed

Lines changed: 42 additions & 9 deletions

File tree

.claude/statusline.py

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import json
44
import sys
5+
import time
56

67
if sys.platform == "win32":
78
sys.stdout.reconfigure(encoding="utf-8")
@@ -11,6 +12,8 @@
1112
BLOCKS = " ▏▎▍▌▋▊▉█"
1213
R = "\033[0m"
1314
DIM = "\033[2m"
15+
GREEN = "\033[38;2;100;200;120m"
16+
RED = "\033[38;2;230;110;110m"
1417

1518

1619
def gradient(pct):
@@ -22,7 +25,7 @@ def gradient(pct):
2225
return f"\033[38;2;255;{max(g, 0)};60m"
2326

2427

25-
def bar(pct, width=10):
28+
def bar(pct, width=6):
2629
pct = min(max(pct, 0), 100)
2730
filled = pct * width / 100
2831
full = int(filled)
@@ -34,24 +37,54 @@ def bar(pct, width=10):
3437
return b
3538

3639

37-
def fmt(label, pct):
40+
def fmt_reset(resets_at):
41+
if not resets_at:
42+
return ""
43+
secs = int(resets_at - time.time())
44+
if secs <= 0:
45+
return ""
46+
if secs < 3600:
47+
return f"{secs // 60}m"
48+
if secs < 86400:
49+
h, m = divmod(secs, 3600)
50+
m //= 60
51+
return f"{h}h{m}m" if m else f"{h}h"
52+
d, h = divmod(secs, 86400)
53+
h //= 3600
54+
return f"{d}d{h}h" if h else f"{d}d"
55+
56+
57+
def fmt(label, pct, reset=""):
3858
p = round(pct)
39-
return f"{label} {gradient(pct)}{bar(pct)} {p}%{R}"
59+
s = f"{label} {gradient(pct)}{bar(pct)} {p}%{R}"
60+
if reset:
61+
s += f" {DIM}{reset}{R}"
62+
return s
4063

4164

4265
model = data.get("model", {}).get("display_name", "Claude")
66+
effort = data.get("effort", {}).get("level")
67+
if effort:
68+
model = f"{model}{DIM}·{effort}{R}"
4369
parts = [model]
4470

4571
ctx = data.get("context_window", {}).get("used_percentage")
4672
if ctx is not None:
4773
parts.append(fmt("ctx", ctx))
4874

49-
five = data.get("rate_limits", {}).get("five_hour", {}).get("used_percentage")
50-
if five is not None:
51-
parts.append(fmt("5h", five))
75+
rl = data.get("rate_limits", {})
76+
five = rl.get("five_hour", {})
77+
if five.get("used_percentage") is not None:
78+
parts.append(fmt("5h", five["used_percentage"], fmt_reset(five.get("resets_at"))))
5279

53-
week = data.get("rate_limits", {}).get("seven_day", {}).get("used_percentage")
54-
if week is not None:
55-
parts.append(fmt("7d", week))
80+
week = rl.get("seven_day", {})
81+
if week.get("used_percentage") is not None:
82+
parts.append(fmt("7d", week["used_percentage"], fmt_reset(week.get("resets_at"))))
83+
84+
cost = data.get("cost", {})
85+
added = cost.get("total_lines_added", 0) or 0
86+
removed = cost.get("total_lines_removed", 0) or 0
87+
if added or removed:
88+
parts.append(f"{GREEN}+{added}{R} {RED}-{removed}{R}")
5689

5790
print(f"{DIM}{R}".join(f" {p} " for p in parts), end="")

0 commit comments

Comments
 (0)