{"id":45927889,"url":"https://github.com/rishiatlan/claude-usage-mac-widget","last_synced_at":"2026-03-02T11:00:33.942Z","repository":{"id":340166545,"uuid":"1164837876","full_name":"rishiatlan/Claude-Usage-Mac-Widget","owner":"rishiatlan","description":"A Widget for Claude Usage on your account","archived":false,"fork":false,"pushed_at":"2026-02-26T18:26:37.000Z","size":2223,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T12:58:14.480Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rishiatlan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-23T14:41:14.000Z","updated_at":"2026-02-26T18:24:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rishiatlan/Claude-Usage-Mac-Widget","commit_stats":null,"previous_names":["rishiatlan/claude-usage-mac-widget"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rishiatlan/Claude-Usage-Mac-Widget","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishiatlan%2FClaude-Usage-Mac-Widget","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishiatlan%2FClaude-Usage-Mac-Widget/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishiatlan%2FClaude-Usage-Mac-Widget/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishiatlan%2FClaude-Usage-Mac-Widget/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rishiatlan","download_url":"https://codeload.github.com/rishiatlan/Claude-Usage-Mac-Widget/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishiatlan%2FClaude-Usage-Mac-Widget/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29966684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T09:33:09.965Z","status":"ssl_error","status_checked_at":"2026-03-01T09:25:48.915Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-28T09:16:34.044Z","updated_at":"2026-03-01T10:00:40.164Z","avatar_url":"https://github.com/rishiatlan.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Usage Mac Widget\n\nA lightweight macOS desktop widget that shows your Claude usage in real time — with pace tracking and reset countdown.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/widget-on-track.png\" width=\"180\" alt=\"Widget — on track\" /\u003e\n  \u0026nbsp;\u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"assets/widget-compact.png\" width=\"80\" alt=\"Widget — compact mode\" /\u003e\n  \u0026nbsp;\u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"assets/widget-still-usable.png\" width=\"180\" alt=\"Widget — still usable\" /\u003e\n  \u0026nbsp;\u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"assets/widget-session-expired.png\" width=\"180\" alt=\"Widget — session expired\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/macOS-13%2B-black\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Swift-5.9+-orange\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-MIT-green\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/No_Dependencies-lightgrey\" /\u003e\n\u003c/p\u003e\n\n---\n\n## Why This Exists\n\nClaude usage limits are easy to hit without noticing. This widget keeps the important signals visible at all times:\n\n- **Current usage** percentage\n- **Pace** vs time elapsed\n- **Reset countdown** timer\n- **Clear status color** (green / orange / red)\n\nNo tab switching. No guesswork.\n\n---\n\n## Features\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"25%\"\u003e\n\n\u003cimg src=\"assets/widget-on-track.png\" width=\"160\" alt=\"Widget showing on-track status\" /\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\n\u003cimg src=\"assets/widget-compact.png\" width=\"80\" alt=\"Widget in compact mode\" /\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\n\u003cimg src=\"assets/widget-still-usable.png\" width=\"160\" alt=\"Widget showing still usable\" /\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\n\u003cimg src=\"assets/widget-session-expired.png\" width=\"160\" alt=\"Widget showing session expired\" /\u003e\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cem\u003eOn track — plenty of room\u003c/em\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cem\u003eCompact mode\u003c/em\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cem\u003eWindow full — still usable\u003c/em\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cem\u003eSession expired — re-authenticate\u003c/em\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n- **Live progress ring** with usage %\n- **Pace tracking** — actual vs expected usage\n- **Reset countdown** timer\n- **Compact mode** — double-click to shrink to a frameless ring; background appears on hover\n- **Always-on-top** floating panel (all Spaces)\n- **Draggable** — remembers position\n- **Auto-refresh** every 30 seconds\n- **Session expiry detection** with red border alert\n- **Cloudflare-aware** — won't falsely show \"Session Expired\"\n- **Multi-limit aware** — when one window is full, shows remaining capacity on other limits\n- **Self-updating** — checks for updates every 24h, one-click update via Settings\n- **Plain-English status** messages\n- **Minimal**, translucent macOS-native UI\n\n---\n\n## Install\n\nThree ways to get the widget — pick the one that fits:\n\n### Option 1: One-Command Install (Recommended)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/rishiatlan/Claude-Usage-Mac-Widget/main/install.sh | bash\n```\n\nDownloads the pre-built app, installs to `/Applications`, removes Gatekeeper quarantine, and launches it. No build tools needed.\n\n### Option 2: Download from GitHub Releases\n\n1. Go to [**Releases**](https://github.com/rishiatlan/Claude-Usage-Mac-Widget/releases/latest)\n2. Download `ClaudeUsage.app.zip`\n3. Unzip and move `ClaudeUsage.app` to `/Applications`\n4. Double-click to launch\n\n\u003e **Gatekeeper warning?** macOS may say the app is from an unidentified developer. Fix: `xattr -dr com.apple.quarantine /Applications/ClaudeUsage.app` or right-click → Open → Open.\n\n### Option 3: Build from Source\n\nRequires macOS 13+ and Xcode Command Line Tools (`xcode-select --install`).\n\n```bash\ngit clone https://github.com/rishiatlan/Claude-Usage-Mac-Widget.git\ncd Claude-Usage-Mac-Widget\nchmod +x build.sh run.sh setup.sh generate-icon.sh\n./build.sh\n./setup.sh          # Interactive credential setup\nopen build/ClaudeUsage.app\n```\n\n### Setup Credentials\n\n1. Right-click the widget → **Settings**\n2. Paste your **Session Key** (from browser cookies — see [How to Get Your Credentials](#how-to-get-your-credentials))\n3. Paste your **Organization ID** (from DevTools Network tab)\n4. Click **Save**\n\n\u003e **Session key expired?** Right-click → Settings → paste a fresh key. Org ID never expires.\n\nThat's it. The widget appears on your desktop with live data.\n\n---\n\n## Usage\n\n| Action | How |\n|--------|------|\n| Open Settings | Right-click → **Settings** |\n| Refresh | Right-click → **Refresh** |\n| Quit | Right-click → **Quit** |\n| Move widget | Click + drag |\n| Compact / Full Size | Double-click widget, or right-click → **Compact** / **Full Size** |\n| Change metric | Settings → **Display Metric** |\n\n### Choosing a Metric\n\n| Metric | Best For |\n|--------|----------|\n| **5-Hour** (Recommended) | Daily pacing — tells you if you can keep chatting right now |\n| **7-Day (All Models)** | Weekly budgeting — tracks total weekly allowance |\n| **7-Day (Sonnet Only)** | Heavy Sonnet usage tracking |\n\n---\n\n## How to Get Your Credentials\n\n`setup.sh` handles this automatically, but if you need to grab them manually:\n\n### Session Key\n\n1. Open **[claude.ai](https://claude.ai)** in Chrome or Safari (logged in)\n2. Open Developer Tools — **`Cmd + Option + I`**\n3. Go to **Application** tab (Chrome) or **Storage** tab (Safari)\n4. Expand **Cookies** → click **https://claude.ai**\n5. Find the row named **`sessionKey`** → copy the full value\n\n\u003e **Note:** Session keys expire periodically (when your browser session refreshes). When this happens, the widget will show a **red \"Session Expired\"** border. Just re-run `./setup.sh` or paste a fresh key in Settings.\n\n### Organization ID\n\n1. Still in DevTools, switch to the **Network** tab\n2. Send any message in a Claude chat\n3. Find any request URL containing `/organizations/` — the UUID after it is your org ID\n\n\u003e **Note:** Org IDs **never expire**. You only need to grab this once. `setup.sh` fetches it automatically from the API.\n\n---\n\n## Security \u0026 Privacy\n\n| Principle | Detail |\n|-----------|--------|\n| **No browser access** | `setup.sh` never reads cookies, Keychain, or browser data — you paste the key yourself |\n| **Masked input** | Session key entry is hidden (`read -s`) and never echoed or logged |\n| **Keychain storage** | Session key stored in macOS Keychain (encrypted, `kSecAttrAccessibleWhenUnlocked`) — not in plain text |\n| **No telemetry** | Zero analytics, zero tracking. Only talks to `claude.ai/api` |\n| **Cloudflare-aware** | Detects Cloudflare challenge pages and handles them gracefully — won't falsely report session expiry |\n| **Smart polling** | Pauses API calls when session expires — resumes when you save fresh credentials |\n| **Open source** | Read every line of `setup.sh` and `ClaudeUsageApp.swift` |\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eUnderstanding Claude Limits\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\nClaude enforces two independent limits:\n\n### 5-Hour Rolling Window\n\n- Tracks the last 5 hours of usage\n- Recovers automatically as time passes\n- Most useful for daily pacing\n- If it hits 100% — you're locked out until older messages age past the 5-hour mark\n\n### 7-Day Weekly Limit\n\n- Total weekly allowance across all models\n- Hard reset once per week\n- If it hits 100% — you're done until the weekly reset regardless of the 5-hour limit\n\nThere's also a **7-Day Sonnet-only** metric for tracking that model separately.\n\n### Status Colors (Pace Tracking)\n\nThe widget compares your actual usage vs expected usage based on elapsed time:\n\n| Color | Meaning | Example |\n|-------|---------|---------|\n| 🟢 Green | More than 5% **below** expected pace | 2h into 5h window, at 30% (expected: 40%) |\n| 🟠 Orange | Within **±5%** of expected pace | 2h into 5h window, at 38% (expected: 40%) |\n| 🔴 Red | More than 5% **above** expected pace | 2h into 5h window, at 60% (expected: 40%) |\n\n### Status Messages\n\n| Message | Meaning |\n|---------|---------|\n| Plenty of room | Under 30%, on track |\n| On track — you're good | On track, above 30% |\n| On pace — be mindful | Roughly at expected pace |\n| Above pace — slow down | Burning faster than expected |\n| Almost out — slow down | Above 90%, exceeding pace |\n| Limit reached — wait for reset | 100% — rate-limited |\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWhat Happens When setup.sh Can't Auto-Fetch\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\nSometimes `setup.sh` can't automatically fetch your org ID. Here's why and what to do:\n\n### Cloudflare Blocks\n\nThe Claude API sits behind Cloudflare, which occasionally challenges `curl` requests with a 403 page. **This does NOT mean your session key is invalid.**\n\n- `setup.sh` will detect the Cloudflare block and tell you\n- It will ask you to enter your org ID manually instead (with step-by-step instructions)\n- The widget app itself uses macOS `URLSession` which passes through Cloudflare — so the widget will work fine even if `curl` was blocked\n\n### Expired Session Key\n\nIf the session key you pasted has already expired:\n\n- `setup.sh` will detect the 401/403 error and tell you it's expired\n- You'll be prompted to paste a fresh key and try again\n- If it still fails, you can save anyway — the widget will show \"Session Expired\" and prompt you to update later\n\n### Network Issues\n\nIf your network is down or the API is unreachable:\n\n- `setup.sh` offers manual entry as a fallback\n- The widget retries with exponential backoff (1s → 2s → 4s) up to 3 times\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eManual Setup (Alternative to setup.sh)\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\nIf you prefer not to use the setup script:\n\n1. **Right-click** the widget → **Settings...**\n2. Paste your **Session Key** (from browser cookies — see [How to Get Your Credentials](#how-to-get-your-credentials))\n3. Paste your **Organization ID** (from DevTools Network tab, or env var)\n4. Select which metric to display\n5. Click **Save**\n\n### Environment Variable Fallback\n\n```bash\nexport CLAUDE_SESSION_KEY=\"sk-ant-sid01-...\"\nexport CLAUDE_ORGANIZATION_ID=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\nopen build/ClaudeUsage.app\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow It Works (Technical)\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\nThe widget polls the Claude API every 30 seconds:\n\n```\nGET https://claude.ai/api/organizations/{orgId}/usage\nCookie: sessionKey={key}\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ClaudeUsageWidget/1.0\n```\n\n**Architecture:** Single-file Swift app (`ClaudeUsageApp.swift`, ~1610 lines) — no Xcode project, no dependencies, no package manager. Compiles with `swiftc` directly.\n\n**Key components:**\n- `FloatingWidgetPanel` — borderless `NSPanel` (always-on-top, all Spaces, draggable)\n- `WidgetView` — SwiftUI with 4 states + compact/full mode, data, setup needed, session expired, loading\n- `WidgetPanelController` — manages lifecycle, persists position, handles compact toggle + panel resize\n- `AppDelegate` — fetching, 30s timer, retry logic, Cloudflare detection\n\n\u003c/details\u003e\n\n---\n\n## Troubleshooting\n\n| Issue | Fix |\n|-------|-----|\n| **\"Setup Needed\"** | Run `./setup.sh` or right-click → Settings → enter credentials |\n| **\"Session Expired\"** (red border) | Re-run `./setup.sh` with a fresh session key. Org ID is remembered. |\n| **Widget not visible** | App runs as background process. Check Activity Monitor → relaunch with `open build/ClaudeUsage.app` |\n| **Widget too big** | Double-click to switch to compact mode (just the ring). Double-click again to restore. |\n| **Data not loading** | Likely authentication — re-run `./setup.sh` |\n| **Stuck at same %** | That's accurate — 5-hour recovers gradually, 7-day resets weekly. Try switching metrics. |\n| **`setup.sh` says \"Cloudflare blocked\"** | Normal. Enter org ID manually when prompted. Widget app is unaffected. |\n| **Gatekeeper blocks the app** | Run `xattr -dr com.apple.quarantine /Applications/ClaudeUsage.app` or right-click → Open → Open |\n| **Build fails (SwiftBridging)** | `sudo rm -rf /Library/Developer/CommandLineTools \u0026\u0026 xcode-select --install` |\n| **Widget gone after restart** | Launch at Login is enabled by default. If you disabled it, re-enable via right-click → Settings |\n\n---\n\n## Roadmap\n\n- [x] Keychain storage for session key — migrated from UserDefaults\n- [x] Launch at Login — enabled by default via `SMAppService`, toggleable in Settings\n- [x] In-app update notifications — blue dot indicator + one-click self-update via Settings\n- [x] Compact mode — frameless ring, double-click or right-click to toggle\n- [x] One-command installer + GitHub Releases distribution\n- [ ] Optional usage history graph\n- [ ] Signed / notarized build\n- [ ] Homebrew formula\n\n---\n\n## Credits\n\nBuilt on top of [claude-usage](https://github.com/amoga-org/claude-usage) by **[amoga.io](https://amoga.io)**. Desktop widget adaptation by [@rishiatlan](https://github.com/rishiatlan).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frishiatlan%2Fclaude-usage-mac-widget","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frishiatlan%2Fclaude-usage-mac-widget","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frishiatlan%2Fclaude-usage-mac-widget/lists"}