# How CodexBar Detects and Displays Provider Incidents: Architecture and Implementation

> Discover how CodexBar detects LLM provider incidents by polling status pages, normalizing data, and displaying real-time health in your macOS menu bar. Learn the architecture.

- Repository: [Peter Steinberger/CodexBar](https://github.com/steipete/CodexBar)
- Tags: architecture
- Published: 2026-07-07

---

**CodexBar discovers service incidents by polling each LLM provider’s public status page, normalizes the heterogeneous data into a unified model, and surfaces real-time health indicators directly in the macOS menu bar.**

CodexBar is an open-source macOS menu-bar application from `steipete/CodexBar` that monitors usage and incident status for various LLM providers. Understanding how it detects and displays provider incidents requires examining its provider-agnostic architecture, which concurrently fetches status feeds from incident.io and statuspage.io endpoints, parses nested JSON structures, and renders unified health indicators in the UI.

## Fetching Status Feeds from Multiple Providers

The ingestion pipeline starts in `Sources/CodexBar/UsageStore+Status.swift`. The method `UsageStore.fetchStatusSummary(_:transport:)` implements a priority-based fetch strategy. It first attempts to reach the provider’s **incident.io** endpoint at the URL pattern `https://<host>/proxy/<host>`. If that request fails, the system falls back to the classic **statuspage.io** JSON endpoints, specifically [`/api/v2/summary.json`](https://github.com/steipete/CodexBar/blob/main//api/v2/summary.json) and [`/api/v2/components.json`](https://github.com/steipete/CodexBar/blob/main//api/v2/components.json).

This dual-path approach ensures resilience when providers migrate between status page vendors or maintain legacy endpoints.

## Parsing Incident.io Responses

When the incident.io endpoint succeeds, the helper `parseIncidentIOSummary(data:)` handles the deeply-nested JSON structure. The parser traverses `structures` → `items` → `groups`/`components` to build an array of `ProviderStatusComponent` objects.

Each component derives its severity through `ProviderStatusComponent.indicator(forStatuspageStatus:)`. For grouped components, the logic collapses children into a single top-level entry whose indicator reflects the worst child state. This aggregation appears in lines 41-48 of `UsageStore+Status.swift`, ensuring the UI never shows a healthy parent hiding critical child issues.

## Parsing Statuspage.io Feeds

For providers using the classic Statuspage format, `parseStatuspageStatus(data:)` extracts the overall `indicator`, optional `description`, and the page-level `updatedAt` timestamp. Complementing this, `parseStatuspageComponents(data:)` constructs a hierarchical tree of components (groups → children) and maps them to the same `ProviderStatusComponent` model used throughout the app.

This normalization allows the rest of the codebase to treat incident.io and statuspage.io data identically, regardless of source format.

## Handling the Google Workspace Edge Case

Google Workspace requires special handling due to its unique JSON schema. The method `fetchWorkspaceStatus(productID:transport:beforeDecoding:)` downloads a large payload from `https://www.google.com/appsstatus/dashboard/incidents.json`.

The decoder employs a custom `StatusFeedDateParser` (lines 22-39 of `UsageStore+Status.swift`) to handle both fractional-second and plain ISO-8601 date formats. After decoding, the system selects the most severe active incident via `indicatorRank(_:)`, then cleans the summary text using `workspaceSummary(from:)` before storage.

## Persisting Status Data in UsageStore

After successful fetches, `UsageStore` persists the normalized data in two dictionaries defined in [`Sources/CodexBar/UsageStore.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/UsageStore.swift). Line 173 stores the `ProviderStatus` in `store.statuses[provider]`, while line 174 stores the component tree in `store.statusComponents[provider]`. The refresh orchestration logic around line 1000 coordinates these updates across multiple providers concurrently.

## Rendering Incidents in the Menu Bar

The UI layer determines which providers expose detailed component breakdowns. In `Sources/CodexBar/StatusItemController+Menu.swift`, the array `statusComponentsSubmenuProviders` (line 1584) acts as a whitelist containing Claude, Codex, and Augment.

For whitelisted providers, `StatusItemController+HostedSubmenus.swift` builds the submenu. The method `statusComponentsRenderSignature(for:)` (line 282) retrieves the component list via `store.statusComponents(for:)`, then `makeHostedSubviewPlaceholderMenu` generates menu items showing each component’s name alongside a colored indicator.

## Mapping Indicators to Visual State

The `ProviderStatusIndicator` enum (defined in [`Sources/CodexBar/UsageStoreSupport.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/UsageStoreSupport.swift), lines 4-9) provides a `hasIssue` flag and human-readable labels. The UI layer uses these properties to color status badges (green for none, yellow for minor, red for major/critical) and to determine whether to display an alert badge on the menu-bar icon.

## Practical Implementation Examples

The following snippets demonstrate the core detection and display flow:

```swift
// Refresh a provider’s status (run anywhere in the app)
await store.refreshProviderStatus(.claude)

```

```swift
// Low-level fetch – used by the refresh logic internally
let (status, components) = try await UsageStore.fetchStatusSummary(
    from: URL(string: "https://status.claude.ai")!)
print(status.indicator)               // → .major, .none, etc.
print(components?.map { $0.name })    // component tree for the submenu

```

```swift
// UI snippet – building the submenu for a provider
func statusComponentsRenderSignature(for provider: UsageProvider) -> String {
    let components = self.store.statusComponents(for: provider)
    // UI builds a list of `ProviderStatusComponent` → menu items with coloured dots
    return components.map { "\($0.name): \($0.indicator)" }.joined(separator: "\n")
}

```

## Summary

- **CodexBar** polls provider status pages via `UsageStore.fetchStatusSummary(_:transport:)` in `UsageStore+Status.swift`, preferring incident.io endpoints with fallback to statuspage.io.
- **incident.io** responses are parsed by `parseIncidentIOSummary(data:)`, which flattens nested group structures and selects the worst child indicator (lines 41-48).
- **statuspage.io** feeds use `parseStatuspageStatus(data:)` and `parseStatuspageComponents(data:)` to extract overall health and component hierarchies.
- **Google Workspace** requires custom date parsing via `StatusFeedDateParser` (lines 22-39) and incident selection via `indicatorRank(_:)`.
- Results are cached in `store.statuses` and `store.statusComponents` (lines 173-174 of [`UsageStore.swift`](https://github.com/steipete/CodexBar/blob/main/UsageStore.swift)).
- The UI whitelists specific providers (Claude, Codex, Augment) in `StatusItemController+Menu.swift` (line 1584) for detailed component submenus.
- `ProviderStatusIndicator` (lines 4-9 of [`UsageStoreSupport.swift`](https://github.com/steipete/CodexBar/blob/main/UsageStoreSupport.swift)) drives the color-coded menu-bar indicators and alert badges.

## Frequently Asked Questions

### How does CodexBar handle providers that switch from statuspage.io to incident.io?

The `fetchStatusSummary(_:transport:)` method implements a fallback chain: it first attempts the incident.io proxy endpoint, and only if that fails does it request the legacy statuspage.io JSON endpoints. This ensures continuous monitoring during provider migrations without requiring app updates.

### Why does the menu bar show a component breakdown for some providers but not others?

The array `statusComponentsSubmenuProviders` in `StatusItemController+Menu.swift` (line 1584) explicitly whitelists Claude, Codex, and Augment for detailed component views. Other providers display only the overall status indicator to keep the menu concise.

### How does CodexBar determine the severity color for a group of components?

When parsing incident.io data, `parseIncidentIOSummary(data:)` collapses grouped components into a single entry whose `ProviderStatusIndicator` reflects the worst state among its children (lines 41-48 of `UsageStore+Status.swift`). This ensures that if any child service is critical, the parent group shows red.

### What happens when Google Workspace returns multiple simultaneous incidents?

The system selects the single most severe active incident using the `indicatorRank(_:)` comparator, then sanitizes the description text via `workspaceSummary(from:)` before displaying it. This prevents the UI from becoming cluttered with multiple overlapping incident notifications.