Skip to content

Add Fable per-model weekly usage#19

Merged
dmelo merged 1 commit into
mainfrom
fable-usage
Jul 8, 2026
Merged

Add Fable per-model weekly usage#19
dmelo merged 1 commit into
mainfrom
fable-usage

Conversation

@dmelo

@dmelo dmelo commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

Adds Fable-specific weekly usage to the app, matching the new Fable limit that claude.ai now shows on its Usage page (alongside "Current session" and "All models").

How

The old OAuthUsageService POSTed a throwaway "hi" message to /v1/messages purely to read anthropic-ratelimit-* response headers — and those headers only expose the session (5h) and all-models (7d) limits, never Fable.

This switches to the structured GET /api/oauth/usage endpoint (the same one claude.ai's Usage page uses). It returns a limits array that includes per-model weekly_scoped entries carrying a display name (Fable), and as a bonus no longer consumes a message token on every refresh.

Changes

  • OAuthUsageService — fetch + Codable-decode GET /api/oauth/usage instead of parsing rate-limit headers. All existing behavior preserved: token file/Keychain lookup + caching, 401/403 → tokenExpired, transient-network retry. ISO8601 reset timestamps (microsecond precision) parsed with a fractional-seconds formatter.
  • Models — new ScopedUsageLimit { name, usage, resetsAt } and WebUsageData.scopedLimits.
  • ContentView — renders a card per scoped weekly limit, so Weekly Limit (Fable) appears now and any future model-scoped limit shows up automatically.
  • Menu bar — new optional "F" ring next to S/W, gated by a new "Show Fable usage" toggle in Settings. Also fixed the ring canvas width, which reserved space for only one separator and clipped the trailing ring once a third segment was added.
  • CLAUDE.md — updated the now-stale architecture note describing OAuthUsageService.

Testing

  • Build succeeds (Release); installed and run locally.
  • Verified the Codable parse against the live endpoint: produces Current Session, Weekly Limit (All Models) 59%, and Weekly Limit (Fable) 69% — matching claude.ai.
  • Confirmed the menu bar ring renders fully (no clipping) with all three toggles enabled.

🤖 Generated with Claude Code

Switch OAuthUsageService from probing rate-limit response headers (via a
throwaway POST /v1/messages) to the structured GET /api/oauth/usage
endpoint. The header approach only exposed session and all-models limits;
the usage endpoint returns a `limits` array that also carries per-model
scoped weekly limits (e.g. Fable) with display names, and no longer burns
a message token on every refresh.

- Models: add ScopedUsageLimit and WebUsageData.scopedLimits
- ContentView: render a card per scoped weekly limit (Fable now, any
  future model-scoped limit automatically)
- Menu bar: add an optional "F" ring alongside S/W, gated by a new
  "Show Fable usage" setting; fix ring width to reserve space for every
  separator (was clipping the trailing ring with 3+ segments)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 7, 2026 19:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the app’s usage reporting to include per-model weekly limits (notably Fable) by switching OAuthUsageService from parsing rate-limit headers on /v1/messages to decoding structured usage data from GET /api/oauth/usage. It also adds UI support to display these scoped limits in the main view and optionally in the menu bar.

Changes:

  • Replace rate-limit-header parsing with GET /api/oauth/usage JSON decoding, including ISO8601 reset timestamp parsing and model-scoped weekly limits extraction.
  • Extend the data model and main UI to render a card per scoped weekly limit.
  • Add a Settings toggle and menu bar “F” ring segment for Fable usage, including updated ring width calculation.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
ClaudeCodeStats/ClaudeCodeStats/Views/SettingsView.swift Adds a new “Show Fable usage” toggle persisted via @AppStorage.
ClaudeCodeStats/ClaudeCodeStats/Services/OAuthUsageService.swift Switches to GET /api/oauth/usage and decodes session/weekly/scoped limits from JSON.
ClaudeCodeStats/ClaudeCodeStats/Models.swift Introduces ScopedUsageLimit and adds scopedLimits to WebUsageData.
ClaudeCodeStats/ClaudeCodeStats/ContentView.swift Renders additional usage cards for each scoped weekly limit.
ClaudeCodeStats/ClaudeCodeStats/ClaudeCodeStatsApp.swift Adds optional “F” ring segment and fixes menu bar ring width measurement for multiple segments.
CLAUDE.md Updates architecture documentation to reflect the new usage endpoint and scoped limits.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 252 to +256
return WebUsageData(
sessionUsage: sessionUtilization * 100,
sessionResetsAt: sessionReset ?? Date(),
weeklyUsage: weeklyUtilization * 100,
weeklyResetsAt: weeklyReset ?? Date(),
sessionUsage: decoded.fiveHour?.utilization ?? 0,
sessionResetsAt: parseDate(decoded.fiveHour?.resetsAt) ?? Date(),
weeklyUsage: decoded.sevenDay?.utilization ?? 0,
weeklyResetsAt: parseDate(decoded.sevenDay?.resetsAt) ?? Date(),
@dmelo dmelo merged commit 8ff8ba5 into main Jul 8, 2026
1 check passed
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.

2 participants