fix(usage): cache Claude quotas without blocking TUI startup

Merged
RA
7d ago
+1572-75

Corrected resubmission of #1555, addressing the macOS startup freeze described in https://github.com/junhoyeo/tokscale/pull/1555#issuecomment-6419410567.

Claude usage requests now reuse a recent successful sample and honor persisted rate-limit cooldowns instead of repeatedly hitting a 429 response. Cached samples remain scoped to the current credential and configuration root, expire after one hour, and show their original observation time when stale. Credential files remain read-only.

The real TUI constructor only reads the shared subscription cache and excludes Claude entries. Entering Usage online starts the existing background fetcher, which checks the current credential before selecting its cached sample or making a request. Offline mode does not restore a Claude card whose account cannot be checked. A blocked macOS Keychain lookup therefore cannot prevent the first frame or stop q from closing the TUI.

Claude requests use a 30-second total HTTP timeout through the existing core client builder, retaining its proxy and TLS settings. This preserves the bounded-request behavior requested alongside #1506 without importing changes to unrelated providers; #1506 remains open as of this revision.

Validation includes real-binary macOS PTY tests with an isolated HOME/config/cache, local pricing fixtures, and a controllably blocked fake security executable. The four cases cover offline startup, online local-tab startup, quitting while Usage waits on Keychain, and excluding an unverified cached Claude card after navigating to Usage. The cache sentinel also has a positive renderer control at the same terminal size, and assertions inspect the complete output after exit. The unchanged closed-PR binary fails the same first-frame watchdog with the fake Keychain held. A dedicated macOS CI job executes these tests; Ubuntu and Windows retain their existing full-suite gates.

Additional regressions cover stalled response headers and a stalled response body, token changes, persisted cooldowns, cache expiry, concurrent writers, and Windows lock contention.

Local validation passed with Rust 1.98.0: cargo fmt --all -- --check, cargo test --locked --workspace --all-features --no-fail-fast (including all four real-binary macOS PTY cases), cargo clippy --locked --workspace --all-features -- -D warnings, and RUSTDOCFLAGS='-D warnings' cargo doc --locked --no-deps --workspace. The Python helper also passes Ruff and mypy. GitHub CI results are tracked on this PR.