import CodexBarCore import Foundation /// App-side provider implementation. /// /// Rules: /// - Provider implementations return *data/behavior descriptors*; the app owns UI. /// - Do not mix identity fields across providers (email/org/plan/loginMethod stays siloed). protocol ProviderImplementation: Sendable { var id: UsageProvider { get } var supportsLoginFlow: Bool { get } @MainActor func presentation(context: ProviderPresentationContext) -> ProviderPresentation @MainActor func observeSettings(_ settings: SettingsStore) @MainActor func isAvailable(context: ProviderAvailabilityContext) -> Bool @MainActor func defaultSourceLabel(context: ProviderSourceLabelContext) -> String? @MainActor func decorateSourceLabel(context: ProviderSourceLabelContext, baseLabel: String) -> String @MainActor func sourceMode(context: ProviderSourceModeContext) -> ProviderSourceMode func detectVersion(context: ProviderVersionContext) async -> String? func makeRuntime() -> (any ProviderRuntime)? /// Optional provider-specific settings toggles to render in the Providers pane. /// /// Important: Providers must not return custom SwiftUI views here. Only shared toggle/action descriptors. @MainActor func settingsToggles(context: ProviderSettingsContext) -> [ProviderSettingsToggleDescriptor] /// Optional provider-specific settings fields to render in the Providers pane. @MainActor func settingsFields(context: ProviderSettingsContext) -> [ProviderSettingsFieldDescriptor] /// Optional provider-specific settings action rows to render in the Providers pane. @MainActor func settingsActions(context: ProviderSettingsContext) -> [ProviderSettingsActionsDescriptor] /// Optional provider-specific settings pickers to render in the Providers pane. @MainActor func settingsPickers(context: ProviderSettingsContext) -> [ProviderSettingsPickerDescriptor] /// Optional provider-specific organizations selection rendered in the Providers pane. @MainActor func settingsOrganizations(context: ProviderSettingsContext) -> ProviderSettingsOrganizationsDescriptor? /// Optional visibility gate for token account settings. @MainActor func tokenAccountsVisibility(context: ProviderSettingsContext, support: TokenAccountSupport) -> Bool /// Optional provider-specific settings snapshot contribution. @MainActor func settingsSnapshot(context: ProviderSettingsSnapshotContext) -> ProviderSettingsSnapshotContribution? /// Optional hook to update provider settings when token accounts change. @MainActor func applyTokenAccountCookieSource(settings: SettingsStore) /// Optional provider-specific menu entries for the usage section. @MainActor func appendUsageMenuEntries(context: ProviderMenuUsageContext, entries: inout [ProviderMenuEntry]) /// Optional provider-specific menu entries for the actions section. @MainActor func appendActionMenuEntries(context: ProviderMenuActionContext, entries: inout [ProviderMenuEntry]) /// Optional override for the login/switch account menu action. @MainActor func loginMenuAction(context: ProviderMenuLoginContext) -> (label: String, action: MenuDescriptor.MenuAction)? /// Optional provider-specific login flow. Returns whether to refresh after completion. @MainActor func runLoginFlow(context: ProviderLoginContext) async -> Bool } extension ProviderImplementation { var supportsLoginFlow: Bool { false } @MainActor func presentation(context _: ProviderPresentationContext) -> ProviderPresentation { ProviderPresentation(detailLine: ProviderPresentation.standardDetailLine) } @MainActor func observeSettings(_ settings: SettingsStore) { _ = settings } @MainActor func isAvailable(context _: ProviderAvailabilityContext) -> Bool { true } @MainActor func defaultSourceLabel(context _: ProviderSourceLabelContext) -> String? { nil } @MainActor func decorateSourceLabel(context _: ProviderSourceLabelContext, baseLabel: String) -> String { baseLabel } @MainActor func sourceMode(context _: ProviderSourceModeContext) -> ProviderSourceMode { .auto } func detectVersion(context: ProviderVersionContext) async -> String? { let detector = ProviderDescriptorRegistry.descriptor(for: self.id).cli.versionDetector return detector?(context.browserDetection) } func makeRuntime() -> (any ProviderRuntime)? { nil } @MainActor func settingsToggles(context _: ProviderSettingsContext) -> [ProviderSettingsToggleDescriptor] { [] } @MainActor func settingsFields(context _: ProviderSettingsContext) -> [ProviderSettingsFieldDescriptor] { [] } @MainActor func settingsActions(context _: ProviderSettingsContext) -> [ProviderSettingsActionsDescriptor] { [] } @MainActor func settingsPickers(context _: ProviderSettingsContext) -> [ProviderSettingsPickerDescriptor] { [] } @MainActor func settingsOrganizations(context _: ProviderSettingsContext) -> ProviderSettingsOrganizationsDescriptor? { nil } @MainActor func tokenAccountsVisibility(context: ProviderSettingsContext, support: TokenAccountSupport) -> Bool { guard support.requiresManualCookieSource else { return true } return !context.settings.tokenAccounts(for: context.provider).isEmpty } @MainActor func settingsSnapshot(context _: ProviderSettingsSnapshotContext) -> ProviderSettingsSnapshotContribution? { nil } @MainActor func applyTokenAccountCookieSource(settings _: SettingsStore) {} @MainActor func appendUsageMenuEntries(context _: ProviderMenuUsageContext, entries _: inout [ProviderMenuEntry]) {} @MainActor func appendActionMenuEntries(context _: ProviderMenuActionContext, entries _: inout [ProviderMenuEntry]) {} @MainActor func loginMenuAction(context _: ProviderMenuLoginContext) -> (label: String, action: MenuDescriptor.MenuAction)? { nil } @MainActor func runLoginFlow(context _: ProviderLoginContext) async -> Bool { false } } struct ProviderLoginContext { unowned let controller: StatusItemController }