# jatinsmu/cc-usage-tracker-menu-bar architecture

> Architecture diagram of the GitHub repository jatinsmu/cc-usage-tracker-menu-bar, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jatinsmu/cc-usage-tracker-menu-bar
- Repository: https://github.com/jatinsmu/cc-usage-tracker-menu-bar

## Overview

1. **What this repo is**
   - `CCUsageBar` is a macOS menu bar utility, written in Swift using Swift Package Manager, that displays Claude Code quota status in real time.
   - It is a single-user desktop app rather than a client/server system: the main runtime is the app bundle itself, plus a polling timer.

2. **App shell and lifecycle**
   - `Sources/CCUsageBar/CCUsageBarApp.swift` is the entry point.
   - The app uses `MenuBarExtra` to create a menu bar item with a popover, and `Resources/Info.plist` sets `LSUIElement=true`, so there is no Dock icon.
   - This makes the app behave like a background menu-bar agent with a UI only when the user clicks the icon.

3. **Central coordination layer**
   - `UsageViewModel.swift` is the main orchestration boundary.
   - It is `@MainActor` and acts as the state holder for the UI, driving:
     - initial load,
     - periodic polling every 15 minutes,
     - manual refresh,
     - update-check state,
     - and error/offline fallback state.
   - This is the main hub where keychain access, API calls, and UI state converge.

4. **Token retrieval boundary**
   - `KeychainReader.swift` reads the Claude Code OAuth token from the macOS Keychain item `Claude Code-credentials`.
   - The repo intentionally reads the existing system Keychain entry rather than storing its own credentials.
   - This boundary matters architecturally because access is asynchronous/off-main-thread to avoid freezing the UI when macOS shows a Keychain prompt.

5. **Remote usage data flow**
   - `UsageClient.swift` performs the network request to Anthropic’s internal OAuth usage endpoint: `https://api.anthropic.com/api/oauth/usage`.
   - The request uses the token from Keychain and the `anthropic-beta: oauth-2025-04-20` header.
   - This is the only runtime network dependency for quota data, and the app relies on standard macOS TLS validation.

6. **Domain model and quota computation**
   - `Models.swift` defines the response/domain shapes such as usage snapshots, windows, limits, and severity levels.
   - `QuotaMetrics.swift` contains the pure calculation logic for percentages, pace, and reset timing.
   - This separation keeps business logic testable and independent from UI, keychain, and networking.

7. **UI composition**
   - `Views/PopoverView.swift` is the popover state machine rendered for the user.
   - `Views/QuotaTrackView.swift` renders the quota bar/track and visual severity cues.
   - `Views/Theme.swift` holds the app’s color palette.
   - The UI is state-driven: the popover shows live usage, reset countdowns, refresh controls, offline/expired-token messaging, and update banners.

8. **Update subsystem**
   - `UpdateChecker.swift` checks GitHub Releases for newer versions and can download the release asset.
   - The user-facing update path is integrated into the popover: when a newer release exists, the app shows an “Update available” banner with an install action.
   - This is a second external dependency besides Anthropic: GitHub Releases is the distribution/update source.

9. **Failure and degradation behavior**
   - The app is designed to keep showing the last known state when the network is unavailable.
   - It also distinguishes between several non-success modes: offline, expired token, not signed in / not connected, and unknown errors.
   - That means the view model does not treat polling failure as fatal; it maps failures into UI states instead of crashing or exiting.

10. **Testing boundary**
   - `Tests/CCUsageBarTests/` focuses on pure logic and parsing:
     - Keychain parsing,
     - model decoding,
     - quota math,
     - update-check logic,
     - usage-client behavior,
     - and view-model state mapping.
   - The tests intentionally avoid real network and Keychain access, which keeps the architecture cleanly separated into testable core logic and platform-integrated adapters.

11. **Build, release, and distribution**
   - `scripts/build-app.sh` assembles `CCUsageBar.app` and signs it locally with a self-signed identity.
   - The repo is not sandboxed, which is intentional because it needs Keychain access and outbound HTTPS to Anthropic.
   - `.github/workflows/ci.yml` validates build and tests on pull requests and main-branch pushes; `.github/workflows/release.yml` publishes tagged releases to GitHub.

12. **Overall architecture in one line**
   - The app is a small macOS menu-bar client with a single stateful view model coordinating three adapters: Keychain for auth, Anthropic for usage data, and GitHub Releases for updates, with pure quota logic and rendering kept separate for testability.

Main entry points: [`Sources/CCUsageBar/UsageViewModel.swift`](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UsageViewModel.swift) (Usage ViewModel), [`Tests/CCUsageBarTests`](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/tree/main/Tests/CCUsageBarTests) (Tests), [`Sources/CCUsageBar/Models.swift`](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Models.swift) (Models), [`Sources/CCUsageBar/QuotaMetrics.swift`](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/QuotaMetrics.swift) (Quota Metrics)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_app["App Shell"]
  node_node_entrypoint["Menu Bar App<br/>swift app entrypoint"]
  node_node_infoplist["App Bundle<br/>bundle config<br/>[Info.plist]"]
end

subgraph group_group_core["Core Logic"]
  node_node_vm["Usage ViewModel<br/>state coordinator"]
  node_node_keychain[("Keychain Reader<br/>auth adapter")]
  node_node_usage_client["Usage Client<br/>api client<br/>[UsageClient.swift]"]
  node_node_update_checker["Update Checker<br/>release client"]
  node_node_models["Models<br/>domain schema<br/>[Models.swift]"]
  node_node_quota_metrics{{"Quota Metrics<br/>calculation logic<br/>[QuotaMetrics.swift]"}}
end

subgraph group_group_ui["User Interface"]
  node_node_popover["Popover View<br/>stateful view<br/>[PopoverView.swift]"]
  node_node_track["Quota Track<br/>visual component"]
  node_node_theme["Theme<br/>style tokens<br/>[Theme.swift]"]
end

subgraph group_group_delivery["Delivery"]
  node_node_tests["Tests<br/>test suite"]
  node_node_build["Build Script<br/>packaging script<br/>[build-app.sh]"]
  node_node_ci["CI Workflow<br/>github actions<br/>[ci.yml]"]
  node_node_release["Release Workflow<br/>github actions<br/>[release.yml]"]
end

node_node_entrypoint -->|"creates"| node_node_vm
node_node_infoplist -->|"configures"| node_node_entrypoint
node_node_vm -->|"reads token"| node_node_keychain
node_node_vm -->|"polls usage"| node_node_usage_client
node_node_vm -->|"checks updates"| node_node_update_checker
node_node_vm -->|"binds state"| node_node_models
node_node_vm -->|"computes ui state"| node_node_quota_metrics
node_node_keychain -->|"auth token"| node_node_usage_client
node_node_usage_client -->|"decodes"| node_node_models
node_node_quota_metrics -->|"derives"| node_node_models
node_node_models -->|"drives"| node_node_popover
node_node_quota_metrics -->|"feeds"| node_node_track
node_node_theme -->|"styles"| node_node_popover
node_node_theme -->|"styles"| node_node_track
node_node_update_checker -->|"banner state"| node_node_popover
node_node_tests -.->|"covers"| node_node_models
node_node_tests -.->|"covers"| node_node_quota_metrics
node_node_tests -.->|"covers"| node_node_usage_client
node_node_tests -.->|"covers"| node_node_update_checker
node_node_tests -.->|"covers"| node_node_vm
node_node_build -->|"packages"| node_node_entrypoint
node_node_ci -->|"runs"| node_node_tests
node_node_release -->|"publishes"| node_node_update_checker

click node_node_entrypoint "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/CCUsageBarApp.swift"
click node_node_infoplist "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Resources/Info.plist"
click node_node_vm "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UsageViewModel.swift"
click node_node_keychain "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/KeychainReader.swift"
click node_node_usage_client "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UsageClient.swift"
click node_node_update_checker "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UpdateChecker.swift"
click node_node_models "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Models.swift"
click node_node_quota_metrics "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/QuotaMetrics.swift"
click node_node_popover "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/PopoverView.swift"
click node_node_track "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/QuotaTrackView.swift"
click node_node_theme "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/Theme.swift"
click node_node_tests "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/tree/main/Tests/CCUsageBarTests"
click node_node_build "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/scripts/build-app.sh"
click node_node_ci "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/.github/workflows/ci.yml"
click node_node_release "https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/.github/workflows/release.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_entrypoint,node_node_infoplist toneBlue
class node_node_vm,node_node_keychain,node_node_usage_client,node_node_update_checker,node_node_models,node_node_quota_metrics toneAmber
class node_node_popover,node_node_track,node_node_theme toneMint
class node_node_tests,node_node_build,node_node_ci,node_node_release toneRose
```

## Components

### App Shell

Menu bar entrypoint and app lifecycle

- [Menu Bar App](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/CCUsageBarApp.swift): swift app entrypoint · Creates the macOS menu bar extra and launches the app shell · `Sources/CCUsageBar/CCUsageBarApp.swift`
- [App Bundle](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Resources/Info.plist): bundle config · Sets the app to run as a background menu-bar agent without a Dock icon · `Resources/Info.plist`

### Core Logic

State, domain model, quota math, and data adapters

- [Usage ViewModel](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UsageViewModel.swift): state coordinator · Main orchestration boundary for polling, refresh, update checks, and UI state · `Sources/CCUsageBar/UsageViewModel.swift`
- [Keychain Reader](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/KeychainReader.swift): auth adapter · Reads the Claude Code token from the macOS Keychain · `Sources/CCUsageBar/KeychainReader.swift`
- [Usage Client](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UsageClient.swift): api client · Fetches quota usage from Anthropic using the OAuth token · `Sources/CCUsageBar/UsageClient.swift`
- [Update Checker](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/UpdateChecker.swift): release client · Checks GitHub Releases for newer versions and fetches install assets · `Sources/CCUsageBar/UpdateChecker.swift`
- [Models](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Models.swift): domain schema · Defines usage snapshots, windows, limits, and severity state · `Sources/CCUsageBar/Models.swift`
- [Quota Metrics](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/QuotaMetrics.swift): calculation logic · Pure computations for percentages, pace, and reset timing · `Sources/CCUsageBar/QuotaMetrics.swift`

### User Interface

Popover rendering and visual components

- [Popover View](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/PopoverView.swift): stateful view · Renders usage state, refresh controls, errors, and update banners · `Sources/CCUsageBar/Views/PopoverView.swift`
- [Quota Track](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/QuotaTrackView.swift): visual component · Draws the quota bar and severity cues · `Sources/CCUsageBar/Views/QuotaTrackView.swift`
- [Theme](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/Sources/CCUsageBar/Views/Theme.swift): style tokens · Central color palette for the popover UI · `Sources/CCUsageBar/Views/Theme.swift`

### Delivery

Build, test, and release automation

- [Tests](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/tree/main/Tests/CCUsageBarTests): test suite · Covers parsing, model decoding, quota math, update logic, client behavior, and state mapping · `Tests/CCUsageBarTests`
- [Build Script](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/scripts/build-app.sh): packaging script · Builds and signs the app bundle locally for distribution · `scripts/build-app.sh`
- [CI Workflow](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/.github/workflows/ci.yml): github actions · Runs build and tests on pull requests and main pushes · `.github/workflows/ci.yml`
- [Release Workflow](https://github.com/jatinsmu/cc-usage-tracker-menu-bar/blob/main/.github/workflows/release.yml): github actions · Publishes tagged releases to GitHub · `.github/workflows/release.yml`

## Connections

- Menu Bar App → Usage ViewModel: creates · Menu bar app instantiates the main state coordinator
- App Bundle → Menu Bar App: configures · Bundle settings make the app run headlessly in the menu bar
- Usage ViewModel → Keychain Reader: reads token · Loads the existing Claude Code credential from Keychain
- Usage ViewModel → Usage Client: polls usage · Fetches quota status on launch, refresh, and timer ticks
- Usage ViewModel → Update Checker: checks updates · Queries GitHub Releases for available upgrades
- Usage ViewModel → Models: binds state · Maps decoded usage data into app-facing domain state
- Usage ViewModel → Quota Metrics: computes ui state · Uses pure quota calculations for progress and timing
- Keychain Reader → Usage Client: auth token · Provides the OAuth token used for the usage request
- Usage Client → Models: decodes · Transforms the API response into domain models
- Quota Metrics → Models: derives · Produces percentages, pace, and reset-related values
- Models → Popover View: drives · Supplies the popover with live usage and status state
- Quota Metrics → Quota Track: feeds · Provides the visual severity and progress values
- Theme → Popover View: styles · Defines the palette used by the popover
- Theme → Quota Track: styles · Defines the quota bar colors and emphasis
- Update Checker → Popover View: banner state · Surfaces available-update messaging and install action
- Tests → Models: covers · Validates decoding and domain shape handling
- Tests → Quota Metrics: covers · Validates quota math and reset calculations
- Tests → Usage Client: covers · Exercises client behavior without real network access
- Tests → Update Checker: covers · Checks release lookup and update-path behavior
- Tests → Usage ViewModel: covers · Validates state mapping and failure-mode handling
- Build Script → Menu Bar App: packages · Build script assembles the app bundle from the Swift sources
- CI Workflow → Tests: runs · CI validates the test suite and build on changes
- Release Workflow → Update Checker: publishes · Release workflow feeds the GitHub Releases update source
