Skip to main content
The ProviderDescriptor struct is the single source of truth for each provider in CodexBar. It defines how to fetch usage data, display the provider in the UI, and configure CLI behavior.

Overview

Every provider in CodexBar is defined by a descriptor that declares:
  • Identity: Unique provider ID
  • Metadata: Display labels, URLs, capabilities
  • Branding: Icon style, resource name, and color
  • Token cost: Whether token-level usage tracking is supported
  • Fetch plan: Available source modes and fetch strategies
  • CLI config: Command name, aliases, and version detection

Structure Definition

id
UsageProvider
required
The unique identifier for this provider (e.g., .codex, .claude, .cursor)
metadata
ProviderMetadata
required
Display labels, capabilities, and URLs for this provider
branding
ProviderBranding
required
Visual identity for the provider
tokenCost
ProviderTokenCostConfig
required
Configuration for token-level cost tracking
fetchPlan
ProviderFetchPlan
required
Defines available source modes and fetch strategy pipeline
cli
ProviderCLIConfig
required
CLI-specific configuration

Methods

fetchOutcome

public func fetchOutcome(context: ProviderFetchContext) async -> ProviderFetchOutcome
Executes the provider’s fetch plan and returns detailed outcome including all attempts. Parameters:
  • context: Fetch context containing runtime mode, settings, and dependencies
Returns: ProviderFetchOutcome with result and attempt history

fetch

public func fetch(context: ProviderFetchContext) async throws -> ProviderFetchResult
Convenience method that executes fetch and unwraps the result. Parameters:
  • context: Fetch context containing runtime mode, settings, and dependencies
Returns: ProviderFetchResult on success Throws: Error if all strategies fail

Example: Defining a Provider

import CodexBarMacroSupport
import Foundation

@ProviderDescriptorRegistration
@ProviderDescriptorDefinition
public enum ClaudeProviderDescriptor {
    static func makeDescriptor() -> ProviderDescriptor {
        ProviderDescriptor(
            id: .claude,
            metadata: ProviderMetadata(
                id: .claude,
                displayName: "Claude",
                sessionLabel: "5-hour",
                weeklyLabel: "Weekly",
                opusLabel: nil,
                supportsOpus: false,
                supportsCredits: true,
                creditsHint: "Credits remaining",
                toggleTitle: "Show Claude usage",
                cliName: "claude",
                defaultEnabled: true,
                isPrimaryProvider: false,
                usesAccountFallback: false,
                dashboardURL: "https://console.anthropic.com",
                statusPageURL: "https://status.anthropic.com"),
            branding: ProviderBranding(
                iconStyle: .claude,
                iconResourceName: "ProviderIcon-claude",
                color: ProviderColor(red: 0.82, green: 0.61, blue: 0.47)),
            tokenCost: ProviderTokenCostConfig(
                supportsTokenCost: true,
                noDataMessage: { "Claude cost summary not available." }),
            fetchPlan: ProviderFetchPlan(
                sourceModes: [.auto, .web, .cli],
                pipeline: ProviderFetchPipeline(
                    resolveStrategies: { context in
                        [
                            ClaudeCLIStrategy(),
                            ClaudeWebStrategy()
                        ]
                    }
                )
            ),
            cli: ProviderCLIConfig(
                name: "claude",
                versionDetector: { /* ... */ })
        )
    }
}

Registry Access

Providers are automatically registered via macros and can be accessed through the registry:
// Get all registered providers
let allProviders = ProviderDescriptorRegistry.all

// Get specific provider descriptor
let claudeDescriptor = ProviderDescriptorRegistry.descriptor(for: .claude)

// Get all provider metadata
let metadata = ProviderDescriptorRegistry.metadata

// Get CLI name mapping
let cliNameMap = ProviderDescriptorRegistry.cliNameMap

Best Practices

Identity silo rule: Never display identity/plan fields from provider A inside provider B UI. Each provider must maintain its own identity scope.
Use the @ProviderDescriptorRegistration macro to automatically register your provider descriptor without manual registry updates.
  • Keep descriptor definitions small and focused
  • Use existing strategies when possible instead of creating duplicates
  • Provide meaningful noDataMessage closures for token cost
  • Set defaultEnabled: false for new providers until thoroughly tested
  • Always provide a statusPageURL or statusLinkURL when available

Build docs developers (and LLMs) love