fix(usage): respect Retry-After on Claude 429 and block requests during cooldown

Merged
ST
2mo ago
+154-0

Summary

When the Claude usage endpoint (/api/oauth/usage) returns HTTP 429, respect the Retry-After header and block subsequent fetch attempts during the cooldown period so manual TUI refreshes do not hammer the rate-limited endpoint.

What changed

  • On 429, read the Retry-After header value and record a cooldown deadline in a process-global atomic
  • fetch_blocking checks the cooldown before making any network request — if active, returns an error immediately without sending a request
  • Once the cooldown expires, the next refresh proceeds normally

Limitations

The endpoint has no publicly documented rate limit. A successful fetch followed by another refresh can still trigger a new 429 and cause Claude to disappear from the Usage tab until the next successful fetch.

Testing

  • 3 new unit tests for cooldown lifecycle (cooldown_is_inactive_by_default, set_cooldown_activates_and_expires, cooldown_blocks_fetch_blocking)
  • Existing 25 tests pass with clear_cooldown() guards added to fetch_blocking tests that share the global cooldown state

Verification

When the API request is blocked with 429:
Screenshot 2026-08-24 at 20 32 13

When the user triggers a refresh(or auto-refresh) during the cooldown period:
Screenshot 2026-08-24 at 20 32 31