Skip to content

feat(usage): Block Usage can hide at 100%, swapping with Block Reset Timer - #89

Closed
eric-engberg wants to merge 1 commit into
developfrom
feat/block-usage-hide-at-limit
Closed

eric-engberg wants to merge 1 commit into
developfrom
feat/block-usage-hide-at-limit

Conversation

@eric-engberg

@eric-engberg eric-engberg commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Standalone, cut from main (rebuilt 2026-10-26 after #71 merged upstream as sirmalloc#697).

What

Block Usage gets a new hide state, when the 5-hour block is at 100% (at-limit, off by default). It's the mirror of Block Reset Timer's under-limit state from #71. With both turned on, the two widgets take turns: the block's percent shows until the limit, then the reset countdown takes its place.

Why

At the limit, the percent stops telling you anything: it reads 100% until the block resets, and what you want to know then is when you can work again. With only #71, a line that pairs the two shows both at the limit:

5h: 100.0%  |  5h reset 1hr 43m

and the percent next to the countdown is noise. Hiding it leaves the one number that matters:

5h reset 1hr 43m

How

  • One shared check. isAtSessionLimit in widgets/shared/usage-display.ts holds feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% #71's test (the usage API's raw percent when there is one, else the payload's, at 100 or more). Block Reset Timer now calls it instead of its inline copy, and Block Usage's new state calls the same function, so the two always flip in the same render: never both, never neither. 99.7% that a whole-number percent shows as 100% still counts as under the limit, as in feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% #71.
  • Same data, no extra requests. feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% #71's prefetch rule asks the usage API for the block's percent for a Block Reset Timer with under-limit. It now covers a Block Usage with at-limit too, through the same cache, so a line with both makes one request, and a line with neither state makes none (tested).
  • What stays the same: with the state off, Block Usage renders exactly as before; unknown usage keeps its no-data behavior ([Timeout] and friends, or hidden with no-data); the TUI preview keeps its sample.
  • The 5h label in front of the countdown: with under-limit on, Block Reset Timer only appears at the limit, so relabeling it (e, e.g. 5h reset ) keeps the 5h label where the percent was. USAGE.md says so next to both states.

Demo

Block Usage (at-limit) and Block Reset Timer (under-limit, label 5h reset ), piped with the 5-hour block at 61% and at 100% (fake rate_limits, reset 1hr 43m away). Before is #71's branch, where the new state does nothing.

Powerline

Before:

Before: at 100% the percent shows next to the countdown, Powerline

After:

After: at 100% only the countdown shows, Powerline

Plain

Before:

Before: at 100% the percent shows next to the countdown, plain

After:

After: at 100% only the countdown shows, plain

Turning the state on in the line editor: h on Block Usage, check "when the 5-hour block is at 100%", and the row reads (hide: at-limit). The preview keeps its sample.

Powerline

Turning on Block Usage's at-limit hide state, Powerline

Plain

Turning on Block Usage's at-limit hide state, plain

Testing

  • bun test: 3209 pass, 0 fail (26 new: the shared check's cases, Block Usage's state, the swap with Block Reset Timer, and the prefetch). bun run lint passes.
    • Block Usage: shown at 60% and 99.7%, hidden at 100% and 100.4%, the API's percent over a lagging payload's (both directions), unknown usage unchanged with and without no-data, state off at 100%, preview unaffected.
    • Swap: for five usage cases, exactly one of Block Usage (at-limit) and Block Reset Timer (under-limit) renders.
    • Prefetch: fetches the block's percent for at-limit even when rate_limits has one, fetches once for a line with both states, doesn't fetch without the state, and falls back to the payload's percent when the fetch fails.
  • Under Node (Vitest), the four changed test files pass, 146 of 146.
  • Built CLI under Bun 1.4.2 and Node 26.10.0, with a fake login and a seeded usage cache (no API call), at 61% and 100%: all runtimes agree in plain and Powerline modes (5h: 61.0% / 5h reset 1hr 42m); the TUI opens and exits cleanly under both.
  • After merging feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% #71's fix that ignores a cached block percent once its block has reset (it now applies to at-limit too, through the same shared check): bun test 3211 pass, 0 fail; bun run lint passes.
  • Rebuilt as one commit on main after feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% #71 merged upstream as feat(usage): Block Reset Timer can hide until the 5-hour block hits 100% sirmalloc/ccstatusline#697, with sirmalloc's fix: the shared check reads the usage API's percent when prefetch accepted one, else the payload's own, never a rejected API percent the merged usage data still holds. New test that a rejected API percent at 100% doesn't hide Block Usage; the Block Usage tests pass the payload's percent through the render context as Block Reset Timer's do. bun test 3277 pass, 0 fail; bun run lint passes.

…Timer

At the 5-hour limit, the block's percent says nothing new: it's 100% until
the reset, and the countdown is what matters. Block Usage gets an "at-limit"
hide state, the mirror of Block Reset Timer's "under-limit": with both on,
the reset countdown takes the percent's place once the block is used up.

Both states read one shared check, isAtSessionLimit, which reads the
percent the way Block Reset Timer's under-limit state does: the usage API's
raw percent when prefetch accepted one, so 99.7% shown as "100%" isn't the
limit yet and a lagging payload doesn't decide, and otherwise the payload's
own percent, never an API percent prefetch rejected as stale. The two
widgets therefore always swap in the same render, never both or neither.
The prefetch asks the usage API for the block's percent for either state,
through the same cache, so a line with both makes one request.
@eric-engberg
eric-engberg changed the base branch from feat/block-reset-hide-under-limit to develop October 26, 2026 17:47
eric-engberg added a commit that referenced this pull request Oct 26, 2026
Brings in #72's review fixes and today's main, which has #71 as upstream
merged it, with sirmalloc's fix: Block Reset Timer's under-limit state
reads the usage API's percent when prefetch accepted one, then the
payload's own, never an API percent prefetch rejected. The shared
isAtSessionLimit check takes the render context for that, as on #89's
rebuilt branch, so Block Usage's at-limit state swaps with it at the
same render. The forecast passes only its usage data: a payload percent
at 100 already ends the forecast.
eric-engberg added a commit that referenced this pull request Oct 26, 2026
Brings in #72's review fixes and today's main, which has #71 as upstream
merged it. #115's cached-answer check and #72's fetch time meet in
fetchUsageData's file cache: a cache that answers the request is served
with its file's write time. Block Usage's at-limit check follows #89's
rebuilt branch, which reads the percent as Block Reset Timer now does.
@eric-engberg
eric-engberg force-pushed the feat/block-usage-hide-at-limit branch from 13abd4b to 1b13f91 Compare October 27, 2026 04:49
@sonarqubecloud

Copy link
Copy Markdown

@eric-engberg

Copy link
Copy Markdown
Owner Author

Merged upstream as sirmalloc#747.

eric-engberg added a commit that referenced this pull request Oct 30, 2026
…build

The branch was rebuilt on today's updated #115 and #80, which hold upstream
main; #71 and #89, which it also merged, are upstream (sirmalloc#697, sirmalloc#747) and in
#115 through main. This keeps the old history so the push is a
fast-forward; the tree is the rebuild's.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant