Skip to content

Commit aad65f8

Browse files
committed
claude: add current session usage to statusline
1 parent 9ecc3f5 commit aad65f8

1 file changed

Lines changed: 44 additions & 8 deletions

File tree

ai/claude/statusline.js

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,51 @@ try {
8484
sections.push({ text: `${percent}%`, bgColor, color });
8585
}
8686

87-
// Rate limit usage
87+
// Rate limit usage. Claude Code currently exposes `five_hour` and `seven_day`
88+
// (each independently present/absent), and only includes `rate_limits` at all
89+
// for Claude.ai subscribers after the first API response. A flat monthly-limit
90+
// plan may populate only a subset of these — so render whichever windows are
91+
// present rather than requiring all of them. `monthly` is mapped speculatively
92+
// for if/when it's surfaced to statuslines.
8893
const rateLimits = input.rate_limits;
89-
if (rateLimits?.five_hour && rateLimits?.seven_day) {
90-
const fiveH = Math.round(rateLimits.five_hour.used_percentage);
91-
const sevenD = Math.round(rateLimits.seven_day.used_percentage);
92-
const maxPct = Math.max(fiveH, sevenD);
93-
const bgColor = maxPct > 75 ? "rgb(226, 0, 0)" : maxPct > 50 ? "rgb(217, 119, 87)" : "rgb(70, 107, 62)";
94-
const color = "rgb(255, 255, 255)";
95-
sections.push({ text: `5h:${fiveH}% 7d:${sevenD}%`, bgColor, color });
94+
let showedRateLimits = false;
95+
if (rateLimits) {
96+
const WINDOW_LABELS = [
97+
["five_hour", "5h"],
98+
["seven_day", "7d"],
99+
["seven_day_opus", "opus7d"],
100+
["seven_day_sonnet", "sonnet7d"],
101+
["monthly", "mo"],
102+
];
103+
104+
const parts = [];
105+
let maxPct = 0;
106+
for (const [key, label] of WINDOW_LABELS) {
107+
const used = rateLimits[key]?.used_percentage;
108+
if (typeof used !== "number") {
109+
continue;
110+
}
111+
const pct = Math.round(used);
112+
parts.push(`${label}:${pct}%`);
113+
maxPct = Math.max(maxPct, pct);
114+
}
115+
116+
if (parts.length) {
117+
const bgColor = maxPct > 75 ? "rgb(226, 0, 0)" : maxPct > 50 ? "rgb(217, 119, 87)" : "rgb(70, 107, 62)";
118+
const color = "rgb(255, 255, 255)";
119+
sections.push({ text: parts.join(" "), bgColor, color });
120+
showedRateLimits = true;
121+
}
122+
}
123+
124+
// Fallback: on plans where no rate-limit windows are exposed (e.g. the flat
125+
// monthly subscription), show per-session API cost instead.
126+
if (!showedRateLimits) {
127+
const cost = input.cost?.total_cost_usd;
128+
if (typeof cost === "number") {
129+
const text = cost < 10 ? `$${cost.toFixed(2)}` : `$${cost.toFixed(1)}`;
130+
sections.push({ text, bgColor: "rgb(58, 90, 100)", color: "rgb(255, 255, 255)" });
131+
}
96132
}
97133

98134
console.log(formatSections(sections));

0 commit comments

Comments
 (0)