Skip to content

Latest commit

 

History

History
254 lines (199 loc) · 8.83 KB

File metadata and controls

254 lines (199 loc) · 8.83 KB

Claude Usage Widget — Project Plan

macOS native floating widget that shows your Claude.ai usage in real-time. Built in SwiftUI. Liquid glass design. Manual-refresh, rate-limit-aware.


1. What Data the API Gives Us

Endpoint: GET https://claude.ai/api/organizations/{orgId}/usage Auth: Full browser cookie string (no OAuth, just Cookie: header)

Response shape

{
  "five_hour": {
    "utilization": 43.0,       // % of 5-hour session used (0–100)
    "resets_at": "2026-03-23T13:30:00Z"
  },
  "seven_day": {
    "utilization": 28.5,       // % of 7-day plan limit used
    "resets_at": "2026-03-27T00:00:00Z"
  },
  "seven_day_sonnet": {        // Pro plan only — absent on free tier
    "utilization": 14.2,
    "resets_at": "2026-03-27T00:00:00Z"
  }
}

Bootstrap endpoint: GET https://claude.ai/api/bootstrap

  • Returns account.lastActiveOrgId if we can't parse it from the cookie.

✅ Data we WILL show

Field Why it matters
five_hour.utilization Most important — am I near a rate-limit right now?
five_hour.resets_at Countdown timer — when can I hammer it again?
seven_day.utilization Weekly burn rate — am I blowing through my plan?
seven_day.resets_at Days until weekly reset
seven_day_sonnet.utilization Pro users: Sonnet-specific limit

❌ Data NOT available from API

  • Per-conversation token counts (not exposed)
  • Model breakdown beyond Sonnet (e.g., Opus vs Haiku)
  • Historical usage data (API only returns current windows)
  • Daily breakdown (only 5h and 7d windows)

2. Rate Limiting Strategy

Claude.ai does NOT publish rate limits for this internal API endpoint. The ClaudeUsageBar reference app uses a 5-minute polling interval — we're going stricter.

Our approach: Manual refresh + smart caching

Trigger Action
App opens Fetch immediately
Manual refresh button tap Fetch immediately
Trackpad swipe-down gesture Fetch (touch-friendly)
Keyboard shortcut ⌘R Fetch
Background timer Every 15 minutes (conservative)
Data age indicator Show "Updated 3m ago" so user knows staleness

Why not constant polling?

  • The endpoint is internal/undocumented — aggressive polling risks rate-limiting or cookie invalidation
  • Usage windows (5h, 7d) don't change second-by-second
  • Manual control respects the API and keeps it responsive

Why 15-minute background refresh vs 5-minute?

  • 5h window changes meaningfully every 10–15 min of heavy use
  • 7d window barely moves in 15 minutes
  • Battery + network friendliness

3. Five Widget Styles

Style 1 — Orbital Rings

Three concentric ring gauges — 5h outer, 7d middle, Sonnet inner. Big percentage hero center. Dynamic accent glow shifts green→red. Best for: People who love data density, ring chart fans.

Style 2 — Command Center

Finance dashboard aesthetic. Hero number (5h %) left, arc gauge right. Three metric pill cards below. Best for: Glanceable at a distance, "Bloomberg terminal" energy.

Style 3 — Liquid Glass ✨

Apple's new iOS 26 / visionOS material. True OS-level blur (NSVisualEffectView). Floating glass pills. Minimal info, maximum beauty. Best for: Desktop aesthetics, clean setups, translucent over wallpaper.

Style 4 — Neon Arc

Dark with vivid neon speedometer arc. Green→yellow→red progression. High drama, perfect for noticing when you're burning through usage. Best for: Gamers, terminal nerds, high-contrast lovers.

Style 5 — Timeline + Usage ⭐ (recommended)

Evolution of the Claude2x widget. Keeps the timeline bar you already love. Adds live usage rings beneath. Week calendar at bottom. Best for: Existing Claude2x users — familiar layout, more data.


4. Project File Structure

ClaudeUsageWidget/
├── ClaudeUsageWidgetApp.swift    ← @main entry
├── AppDelegate.swift             ← Floating window config
├── Models/
│   └── UsageModel.swift          ← UsageData, UsageWindow, UsageLevel
├── Services/
│   └── APIService.swift          ← Fetches /usage endpoint + bootstrap
├── Views/
│   ├── ShowcaseView.swift         ← 5-style comparison picker window
│   ├── Components/
│   │   ├── GlassCard.swift        ← LiquidGlass modifier, backgrounds, helpers
│   │   └── CircularGauge.swift    ← RingGauge, ArcGauge, UsageBar
│   └── Styles/
│       ├── Style1_OrbitalRings.swift
│       ├── Style2_CommandCenter.swift
│       ├── Style3_LiquidGlass.swift
│       ├── Style4_NeonArc.swift
│       └── Style5_TimelineUsage.swift

5. How to Create the Xcode Project

  1. Open Xcode → File › New › Project
  2. Platform: macOS, Template: App
  3. Name: ClaudeUsageWidget, Language: Swift, Interface: SwiftUI
  4. Uncheck "Include Tests"
  5. Save to: ~/Documents/Projects/claude-usage/
  6. Delete the default ContentView.swift and ClaudeUsageWidgetApp.swift
  7. Drag in all the files from ClaudeUsageWidget/ (preserve folder structure)
  8. In project settings → Signing: set your Team
  9. Add NSAppTransportSecurity to Info.plist if needed for HTTP (not needed — claude.ai is HTTPS)
  10. Build & Run → the showcase window opens

6. After You Pick a Style

Once you choose the style you like:

Phase 2 — Polish the chosen widget

  • Fine-tune layout, sizing, padding
  • Add Settings popover (paste cookie, adjust refresh interval)
  • Add menu bar icon option (tiny usage % in menu bar)
  • Local history tracking (store last 7 days of API snapshots in UserDefaults)
  • History mini-chart (area chart of 5h usage over time)
  • Notifications: alert when 5h usage > 80%
  • Launch at login support

Phase 3 — Menu bar mode

  • Option to run as menu bar item only (no floating window)
  • Dropdown popover shows the chosen widget style
  • Keyboard shortcut to show/hide

Phase 4 — Sonnet awareness (Pro+)

  • If seven_day_sonnet present: show Pro badge
  • Separate ring for Opus vs Sonnet (if API ever exposes it)

7. Refresh Touch Gesture Ideas

Beyond the refresh button, you can add:

Interaction Implementation
Swipe down on widget DragGesture with .onEnded { if offset > 40 { refresh() } }
Double tap .onTapGesture(count: 2) { refresh() }
Shake (trackpad Force Touch) NSEvent pressure detection
Menu bar click Clicking menu bar icon always refreshes
⌘R keyboard shortcut .keyboardShortcut("r", modifiers: .command)
Long press .onLongPressGesture(minimumDuration: 0.5) { refresh() }

Recommended for v1: Refresh button + double-tap + ⌘R.


8. Cookie Authentication Notes

The cookie string from .env includes:

  • sessionKey — the primary auth token
  • lastActiveOrg — org UUID (org-bound API calls)
  • cf_clearance — Cloudflare verification (expires every ~24h!)
  • __cf_bm — Cloudflare bot management (short-lived)

The cf_clearance cookie WILL expire — the app will show an error. The user must paste a fresh cookie from their browser.

Future improvement: A "Cookie expired" banner with a one-click workflow to open claude.ai and paste the new cookie.


9. Design Language

Colors

Token Hex Usage
Claude Orange #C96442 Brand, today dot, accents
Claude Dark #0F0D0B App background
Claude Card #1A1714 Card fills
Healthy #22C55E Low usage
Moderate #F59E0B 50–75% usage
High #F97316 75–90% usage
Critical #EF4444 >90% usage
Sky Blue #38BDF8 7-day ring
Violet #A78BFA Sonnet ring

Typography

  • Display numbers: .system(size: X, weight: .black, design: .rounded)
  • Labels: .system(size: X, weight: .black, design: .rounded) + kerning
  • Timestamps/sub: .system(size: X, weight: .medium, design: .monospaced)

Liquid Glass recipe

  1. NSVisualEffectView(.hudWindow, .behindWindow) — true OS blur
  2. Color.white.opacity(0.06) — frosted tint
  3. Top gradient: white 14% → white 4% → clear
  4. Bottom gradient: clear → black 18%
  5. Border: LinearGradient from white 28% (top-leading) to white 5% (bottom-trailing), 0.9pt

10. Development Checklist

Current status

  • API response structure documented
  • APIService (fetch + parse + bootstrap)
  • UsageModel (data types + levels)
  • Component library (GlassCard, CircularGauge, AnimatedBackground)
  • Style 1: Orbital Rings
  • Style 2: Command Center
  • Style 3: Liquid Glass
  • Style 4: Neon Arc
  • Style 5: Timeline + Usage
  • ShowcaseView (comparison picker)
  • AppDelegate (floating window)
  • Create Xcode project + add files
  • Pick winner style
  • Build the final polished widget

Last updated: 2026-03-23