import CodexBarCoreimport Foundation @MainActorstruct MenuDescriptor { struct SubmenuItem: Equatable { let title: String let action: MenuAction? let isEnabled: Bool let isChecked: Bool init(title: String, action: MenuAction?, isEnabled: Bool = true, isChecked: Bool = false) { self.title = title self.action = action self.isEnabled = isEnabled self.isChecked = isChecked } } struct Section { var entries: [Entry] } enum Entry { case text(String, TextStyle) case action(String, MenuAction) case submenu(String, String?, [SubmenuItem]) case divider } enum MenuActionSystemImage: String { case refresh = "arrow.clockwise" case dashboard = "chart.bar" case statusPage = "waveform.path.ecg" case changelog = "list.bullet.rectangle" case addAccount = "plus" case systemAccount = "person.crop.circle" case switchAccount = "key" case openTerminal = "terminal" case loginToProvider = "arrow.right.square" case settings = "gearshape" case about = "info.circle" case quit = "xmark.rectangle" case copyError = "doc.on.doc" } enum TextStyle { case headline case primary case secondary } enum MenuAction: Equatable { case installUpdate case refresh case refreshAugmentSession case dashboard case statusPage case changelog case addCodexAccount case requestCodexSystemPromotion(UUID) case addProviderAccount(UsageProvider) case switchAccount(UsageProvider) case openTerminal(command: String) case loginToProvider(url: String) case settings case about case quit case copyError(String) } var sections: [Section] static func build( provider: UsageProvider?, store: UsageStore, settings: SettingsStore, account: AccountInfo, managedCodexAccountCoordinator: ManagedCodexAccountCoordinator? = nil, codexAccountPromotionCoordinator: CodexAccountPromotionCoordinator? = nil, updateReady: Bool, includeContextualActions: Bool = true) -> MenuDescriptor { var sections: [Section] = [] if let provider { let fallbackAccount = store.accountInfo(for: provider) sections.append(Self.usageSection(for: provider, store: store, settings: settings)) if let accountSection = Self.accountSection( for: provider, store: store, settings: settings, account: fallbackAccount) { sections.append(accountSection) } } else { var addedUsage = false for enabledProvider in store.enabledProviders() { sections.append(Self.usageSection(for: enabledProvider, store: store, settings: settings)) addedUsage = true } if addedUsage { if let accountProvider = Self.accountProviderForCombined(store: store), let fallbackAccount = Optional(store.accountInfo(for: accountProvider)), let accountSection = Self.accountSection( for: accountProvider, store: store, settings: settings, account: fallbackAccount) { sections.append(accountSection) } } else { sections.append(Section(entries: [.text(L("No usage configured."), .secondary)])) } } if includeContextualActions { let actions = Self.actionsSection( for: provider, store: store, account: account, managedCodexAccountCoordinator: managedCodexAccountCoordinator, codexAccountPromotionCoordinator: codexAccountPromotionCoordinator) if !actions.entries.isEmpty { sections.append(actions) } } sections.append(Self.metaSection(updateReady: updateReady)) return MenuDescriptor(sections: sections) } private static func usageSection( for provider: UsageProvider, store: UsageStore, settings: SettingsStore) -> Section { let meta = store.metadata(for: provider) var entries: [Entry] = [] let headlineText: String = { if let ver = Self.versionNumber(for: provider, store: store) { return "\(meta.displayName) \(ver)" } return meta.displayName }() entries.append(.text(headlineText, .headline)) if let snap = store.snapshot(for: provider) { let resetStyle = settings.resetTimeDisplayStyle let labels = Self.rateWindowLabels(provider: provider, metadata: meta, snapshot: snap) if let primary = snap.primary { let primaryDetail = primary.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) let primaryDescriptionIsDetail = provider == .warp || provider == .kilo || provider == .abacus || provider == .deepseek || provider == .azureopenai || provider == .mimo let primaryWindow = if primaryDescriptionIsDetail { // Some providers use resetDescription for non-reset detail // (e.g., "Unlimited", "X/Y credits"). Avoid rendering it as a "Resets ..." line. RateWindow( usedPercent: primary.usedPercent, windowMinutes: primary.windowMinutes, resetsAt: primary.resetsAt, resetDescription: nil) } else { primary } Self.appendRateWindow( entries: &entries, title: labels.primary, window: primaryWindow, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed) if primaryDescriptionIsDetail, let primaryDetail, !primaryDetail.isEmpty { entries.append(.text(primaryDetail, .secondary)) } if provider == .crof, primary.resetsAt != nil, let detail = primary.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines), !detail.isEmpty { entries.append(.text(detail, .secondary)) } if provider == .abacus, let pace = store.weeklyPace(provider: provider, window: primary) { let paceSummary = UsagePaceText.weeklySummary(pace: pace) entries.append(.text(paceSummary, .secondary)) } if let paceSummary = UsagePaceText.sessionSummary(provider: provider, window: primary) { entries.append(.text(paceSummary, .secondary)) } } if let weekly = snap.secondary { let weeklyResetOverride: String? = { guard provider == .warp || provider == .kilo || provider == .perplexity || provider == .crof else { return nil } let detail = weekly.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) guard let detail, !detail.isEmpty else { return nil } if provider == .kilo, weekly.resetsAt != nil { return nil } return detail }() Self.appendRateWindow( entries: &entries, title: labels.secondary, window: weekly, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed, resetOverride: weeklyResetOverride) if provider == .kilo, weekly.resetsAt != nil, let detail = weekly.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines), !detail.isEmpty { entries.append(.text(detail, .secondary)) } if let pace = store.weeklyPace(provider: provider, window: weekly) { let paceSummary = UsagePaceText.weeklySummary(pace: pace) entries.append(.text(paceSummary, .secondary)) } } if labels.showsTertiary, let opus = snap.tertiary { // Perplexity purchased credits don't reset; show the balance as plain text. let opusResetOverride: String? = provider == .perplexity ? opus.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) : nil Self.appendRateWindow( entries: &entries, title: labels.tertiary, window: opus, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed, resetOverride: opusResetOverride) } Self.appendProviderUsageSummaries(entries: &entries, snapshot: snap) } else { entries.append(.text(L("No usage yet"), .secondary)) } let usageContext = ProviderMenuUsageContext( provider: provider, store: store, settings: settings, metadata: meta, snapshot: store.snapshot(for: provider)) ProviderCatalog.implementation(for: provider)? .appendUsageMenuEntries(context: usageContext, entries: &entries) return Section(entries: entries) } private static func appendProviderUsageSummaries( entries: inout [Entry], snapshot: UsageSnapshot) { if let cost = snapshot.providerCost { if cost.currencyCode == "Quota" { let used = String(format: "%.0f", cost.used) let limit = String(format: "%.0f", cost.limit) entries.append(.text("\(L("Quota")): \(used) / \(limit)", .primary)) } } if let openAIAPIUsage = snapshot.openAIAPIUsage { Self.appendOpenAIAPIUsageSummary(entries: &entries, usage: openAIAPIUsage) } if let claudeAdminAPIUsage = snapshot.claudeAdminAPIUsage { Self.appendClaudeAdminAPIUsageSummary(entries: &entries, usage: claudeAdminAPIUsage) } if let openRouterUsage = snapshot.openRouterUsage { Self.appendOpenRouterUsageSummary(entries: &entries, usage: openRouterUsage) } if let poeUsage = snapshot.poeUsage, !poeUsage.daily.isEmpty { Self.appendPoeUsageSummary(entries: &entries, usage: poeUsage) } if let mistralUsage = snapshot.mistralUsage, !mistralUsage.daily.isEmpty { Self.appendMistralUsageSummary(entries: &entries, usage: mistralUsage) } if let mimoUsage = snapshot.mimoUsage { entries.append(.text("\(L("Balance")): \(mimoUsage.balanceDetail)", .primary)) } } private static func appendOpenAIAPIUsageSummary( entries: inout [Entry], usage: OpenAIAPIUsageSnapshot) { let today = usage.latestDay let last7 = usage.last7Days let last30 = usage.last30Days let historyLabel = usage.historyWindowLabel entries.append(.text( "\(L("Today")): \(UsageFormatter.usdString(today.costUSD)) · " + "\(UsageFormatter.tokenCountString(today.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "7d: \(UsageFormatter.usdString(last7.costUSD)) · " + "\(UsageFormatter.tokenCountString(last7.requests)) \(L("requests"))", .secondary)) entries.append(.text( "\(historyLabel): \(UsageFormatter.usdString(last30.costUSD)) · " + "\(UsageFormatter.tokenCountString(last30.requests)) \(L("requests"))", .secondary)) if let topModel = usage.topModels.first?.name { entries.append(.text("\(L("Top model")): \(topModel)", .secondary)) } } private static func appendClaudeAdminAPIUsageSummary( entries: inout [Entry], usage: ClaudeAdminAPIUsageSnapshot) { let today = usage.latestDay let last7 = usage.last7Days let last30 = usage.last30Days entries.append(.text( "\(L("Today")): \(UsageFormatter.usdString(today.costUSD)) · " + "\(UsageFormatter.tokenCountString(today.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "7d: \(UsageFormatter.usdString(last7.costUSD)) · " + "\(UsageFormatter.tokenCountString(last7.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "30d: \(UsageFormatter.usdString(last30.costUSD)) · " + "\(UsageFormatter.tokenCountString(last30.totalTokens)) \(L("tokens"))", .secondary)) if let topModel = usage.topModels.first?.name { entries.append(.text("\(L("Top model")): \(topModel)", .secondary)) } } private static func appendOpenRouterUsageSummary( entries: inout [Entry], usage: OpenRouterUsageSnapshot) { if let daily = usage.keyUsageDaily { entries.append(.text("\(L("Today")): \(UsageFormatter.usdString(daily))", .secondary)) } if let weekly = usage.keyUsageWeekly { entries.append(.text("\(L("Week")): \(UsageFormatter.usdString(weekly))", .secondary)) } if let monthly = usage.keyUsageMonthly { entries.append(.text("\(L("Month")): \(UsageFormatter.usdString(monthly))", .secondary)) } } private static func appendMistralUsageSummary( entries: inout [Entry], usage: MistralUsageSnapshot) { let latest = usage.daily.last if let latest { entries.append(.text( "\(L("Latest")): \(usage.currencySymbol)\(String(format: "%.4f", max(0, latest.cost))) · " + "\(UsageFormatter.tokenCountString(latest.totalTokens)) \(L("tokens"))", .secondary)) } let totalTokens = usage.totalInputTokens + usage.totalCachedTokens + usage.totalOutputTokens entries.append(.text( "\(L("Month")): \(usage.currencySymbol)\(String(format: "%.4f", max(0, usage.totalCost))) · " + "\(UsageFormatter.tokenCountString(totalTokens)) \(L("tokens"))", .secondary)) if let top = Self.topMistralModel(from: usage.daily) { entries.append(.text("\(L("Top model")): \(top)", .secondary)) } } private static func topMistralModel(from entries: [MistralDailyUsageBucket]) -> String? { var tokens: [String: Int] = [:] for entry in entries { for model in entry.models { tokens[model.name, default: 0] += model.totalTokens } } return tokens.max { if $0.value == $1.value { return $0.key > $1.key } return $0.value < $1.value }?.key } private static func appendPoeUsageSummary( entries: inout [Entry], usage: PoeUsageHistorySnapshot) { let today = usage.latestDay let week = usage.last7Days let month = usage.last30Days let todayCostSuffix = today.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" let weekCostSuffix = week.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" let monthCostSuffix = month.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" entries.append(.text( "\(L("Today")): \(Self.pointsString(today.points)) · " + "\(UsageFormatter.tokenCountString(today.requests)) \(L("requests"))\(todayCostSuffix)", .secondary)) entries.append(.text( "7d: \(Self.pointsString(week.points)) · " + "\(UsageFormatter.tokenCountString(week.requests)) \(L("requests"))\(weekCostSuffix)", .secondary)) entries.append(.text( "30d: \(Self.pointsString(month.points)) · " + "\(UsageFormatter.tokenCountString(month.requests)) \(L("requests"))\(monthCostSuffix)", .secondary)) if let topModel = usage.topModels.first { entries.append( .text( "\(L("Top model")): \(topModel.name) (\(Self.pointsString(topModel.points)))", .secondary)) } if !usage.topUsageTypes.isEmpty { let summary = usage.topUsageTypes .prefix(2) .map { "\($0.name): \(Self.pointsString($0.points))" } .joined(separator: " · ") entries.append(.text("Usage mix: \(summary)", .secondary)) } let recent = usage.recentEntries(limit: 3) if !recent.isEmpty { entries.append(.text("Recent activity:", .secondary)) for entry in recent { let stamp = Self.poeTimeString(entry.createdAt) entries.append(.text( "\(stamp) · \(entry.model) · \(Self.pointsString(entry.points))", .secondary)) } } } private static func pointsString(_ points: Double) -> String { let value = max(0, points) if value.rounded() == value { return "\(UsageFormatter.tokenCountString(Int(value))) points" } return "\(String(format: "%.1f", value)) points" } private static func poeTimeString(_ date: Date) -> String { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = .current formatter.dateFormat = "MM-dd HH:mm" return formatter.string(from: date) } private static func accountSection( for provider: UsageProvider, store: UsageStore, settings: SettingsStore, account: AccountInfo) -> Section? { let snapshot = store.snapshot(for: provider) let metadata = store.metadata(for: provider) let entries = Self.accountEntries( provider: provider, snapshot: snapshot, metadata: metadata, fallback: account, hidePersonalInfo: settings.hidePersonalInfo) guard !entries.isEmpty else { return nil } return Section(entries: entries) } private static func accountEntries( provider: UsageProvider, snapshot: UsageSnapshot?, metadata: ProviderMetadata, fallback: AccountInfo, hidePersonalInfo: Bool) -> [Entry] { var entries: [Entry] = [] let emailText = snapshot?.accountEmail(for: provider)? .trimmingCharacters(in: .whitespacesAndNewlines) let loginMethodText = snapshot?.loginMethod(for: provider)? .trimmingCharacters(in: .whitespacesAndNewlines) let redactedEmail = PersonalInfoRedactor.redactEmail(emailText, isEnabled: hidePersonalInfo) if let emailText, !emailText.isEmpty { entries.append(.text("\(L("Account")): \(redactedEmail)", .secondary)) } if provider == .kiro { if let plan = snapshot?.kiroUsage?.displayPlanName, !plan.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { entries.append(.text("\(L("Plan")): \(plan)", .secondary)) } if let loginMethodText, !loginMethodText.isEmpty { entries.append(.text("\(L("Auth")): \(loginMethodText)", .secondary)) } if let overages = snapshot?.kiroUsage?.overagesStatus, !overages.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { entries.append(.text("\(L("Overages")): \(overages)", .secondary)) } } else if provider == .kilo {Lines 1–500 of 779. Load more
import CodexBarCore import Foundation @MainActor struct MenuDescriptor { struct SubmenuItem: Equatable { let title: String let action: MenuAction? let isEnabled: Bool let isChecked: Bool init(title: String, action: MenuAction?, isEnabled: Bool = true, isChecked: Bool = false) { self.title = title self.action = action self.isEnabled = isEnabled self.isChecked = isChecked } } struct Section { var entries: [Entry] } enum Entry { case text(String, TextStyle) case action(String, MenuAction) case submenu(String, String?, [SubmenuItem]) case divider } enum MenuActionSystemImage: String { case refresh = "arrow.clockwise" case dashboard = "chart.bar" case statusPage = "waveform.path.ecg" case changelog = "list.bullet.rectangle" case addAccount = "plus" case systemAccount = "person.crop.circle" case switchAccount = "key" case openTerminal = "terminal" case loginToProvider = "arrow.right.square" case settings = "gearshape" case about = "info.circle" case quit = "xmark.rectangle" case copyError = "doc.on.doc" } enum TextStyle { case headline case primary case secondary } enum MenuAction: Equatable { case installUpdate case refresh case refreshAugmentSession case dashboard case statusPage case changelog case addCodexAccount case requestCodexSystemPromotion(UUID) case addProviderAccount(UsageProvider) case switchAccount(UsageProvider) case openTerminal(command: String) case loginToProvider(url: String) case settings case about case quit case copyError(String) } var sections: [Section] static func build( provider: UsageProvider?, store: UsageStore, settings: SettingsStore, account: AccountInfo, managedCodexAccountCoordinator: ManagedCodexAccountCoordinator? = nil, codexAccountPromotionCoordinator: CodexAccountPromotionCoordinator? = nil, updateReady: Bool, includeContextualActions: Bool = true) -> MenuDescriptor { var sections: [Section] = [] if let provider { let fallbackAccount = store.accountInfo(for: provider) sections.append(Self.usageSection(for: provider, store: store, settings: settings)) if let accountSection = Self.accountSection( for: provider, store: store, settings: settings, account: fallbackAccount) { sections.append(accountSection) } } else { var addedUsage = false for enabledProvider in store.enabledProviders() { sections.append(Self.usageSection(for: enabledProvider, store: store, settings: settings)) addedUsage = true } if addedUsage { if let accountProvider = Self.accountProviderForCombined(store: store), let fallbackAccount = Optional(store.accountInfo(for: accountProvider)), let accountSection = Self.accountSection( for: accountProvider, store: store, settings: settings, account: fallbackAccount) { sections.append(accountSection) } } else { sections.append(Section(entries: [.text(L("No usage configured."), .secondary)])) } } if includeContextualActions { let actions = Self.actionsSection( for: provider, store: store, account: account, managedCodexAccountCoordinator: managedCodexAccountCoordinator, codexAccountPromotionCoordinator: codexAccountPromotionCoordinator) if !actions.entries.isEmpty { sections.append(actions) } } sections.append(Self.metaSection(updateReady: updateReady)) return MenuDescriptor(sections: sections) } private static func usageSection( for provider: UsageProvider, store: UsageStore, settings: SettingsStore) -> Section { let meta = store.metadata(for: provider) var entries: [Entry] = [] let headlineText: String = { if let ver = Self.versionNumber(for: provider, store: store) { return "\(meta.displayName) \(ver)" } return meta.displayName }() entries.append(.text(headlineText, .headline)) if let snap = store.snapshot(for: provider) { let resetStyle = settings.resetTimeDisplayStyle let labels = Self.rateWindowLabels(provider: provider, metadata: meta, snapshot: snap) if let primary = snap.primary { let primaryDetail = primary.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) let primaryDescriptionIsDetail = provider == .warp || provider == .kilo || provider == .abacus || provider == .deepseek || provider == .azureopenai || provider == .mimo let primaryWindow = if primaryDescriptionIsDetail { // Some providers use resetDescription for non-reset detail // (e.g., "Unlimited", "X/Y credits"). Avoid rendering it as a "Resets ..." line. RateWindow( usedPercent: primary.usedPercent, windowMinutes: primary.windowMinutes, resetsAt: primary.resetsAt, resetDescription: nil) } else { primary } Self.appendRateWindow( entries: &entries, title: labels.primary, window: primaryWindow, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed) if primaryDescriptionIsDetail, let primaryDetail, !primaryDetail.isEmpty { entries.append(.text(primaryDetail, .secondary)) } if provider == .crof, primary.resetsAt != nil, let detail = primary.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines), !detail.isEmpty { entries.append(.text(detail, .secondary)) } if provider == .abacus, let pace = store.weeklyPace(provider: provider, window: primary) { let paceSummary = UsagePaceText.weeklySummary(pace: pace) entries.append(.text(paceSummary, .secondary)) } if let paceSummary = UsagePaceText.sessionSummary(provider: provider, window: primary) { entries.append(.text(paceSummary, .secondary)) } } if let weekly = snap.secondary { let weeklyResetOverride: String? = { guard provider == .warp || provider == .kilo || provider == .perplexity || provider == .crof else { return nil } let detail = weekly.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) guard let detail, !detail.isEmpty else { return nil } if provider == .kilo, weekly.resetsAt != nil { return nil } return detail }() Self.appendRateWindow( entries: &entries, title: labels.secondary, window: weekly, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed, resetOverride: weeklyResetOverride) if provider == .kilo, weekly.resetsAt != nil, let detail = weekly.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines), !detail.isEmpty { entries.append(.text(detail, .secondary)) } if let pace = store.weeklyPace(provider: provider, window: weekly) { let paceSummary = UsagePaceText.weeklySummary(pace: pace) entries.append(.text(paceSummary, .secondary)) } } if labels.showsTertiary, let opus = snap.tertiary { // Perplexity purchased credits don't reset; show the balance as plain text. let opusResetOverride: String? = provider == .perplexity ? opus.resetDescription?.trimmingCharacters(in: .whitespacesAndNewlines) : nil Self.appendRateWindow( entries: &entries, title: labels.tertiary, window: opus, resetStyle: resetStyle, showUsed: settings.usageBarsShowUsed, resetOverride: opusResetOverride) } Self.appendProviderUsageSummaries(entries: &entries, snapshot: snap) } else { entries.append(.text(L("No usage yet"), .secondary)) } let usageContext = ProviderMenuUsageContext( provider: provider, store: store, settings: settings, metadata: meta, snapshot: store.snapshot(for: provider)) ProviderCatalog.implementation(for: provider)? .appendUsageMenuEntries(context: usageContext, entries: &entries) return Section(entries: entries) } private static func appendProviderUsageSummaries( entries: inout [Entry], snapshot: UsageSnapshot) { if let cost = snapshot.providerCost { if cost.currencyCode == "Quota" { let used = String(format: "%.0f", cost.used) let limit = String(format: "%.0f", cost.limit) entries.append(.text("\(L("Quota")): \(used) / \(limit)", .primary)) } } if let openAIAPIUsage = snapshot.openAIAPIUsage { Self.appendOpenAIAPIUsageSummary(entries: &entries, usage: openAIAPIUsage) } if let claudeAdminAPIUsage = snapshot.claudeAdminAPIUsage { Self.appendClaudeAdminAPIUsageSummary(entries: &entries, usage: claudeAdminAPIUsage) } if let openRouterUsage = snapshot.openRouterUsage { Self.appendOpenRouterUsageSummary(entries: &entries, usage: openRouterUsage) } if let poeUsage = snapshot.poeUsage, !poeUsage.daily.isEmpty { Self.appendPoeUsageSummary(entries: &entries, usage: poeUsage) } if let mistralUsage = snapshot.mistralUsage, !mistralUsage.daily.isEmpty { Self.appendMistralUsageSummary(entries: &entries, usage: mistralUsage) } if let mimoUsage = snapshot.mimoUsage { entries.append(.text("\(L("Balance")): \(mimoUsage.balanceDetail)", .primary)) } } private static func appendOpenAIAPIUsageSummary( entries: inout [Entry], usage: OpenAIAPIUsageSnapshot) { let today = usage.latestDay let last7 = usage.last7Days let last30 = usage.last30Days let historyLabel = usage.historyWindowLabel entries.append(.text( "\(L("Today")): \(UsageFormatter.usdString(today.costUSD)) · " + "\(UsageFormatter.tokenCountString(today.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "7d: \(UsageFormatter.usdString(last7.costUSD)) · " + "\(UsageFormatter.tokenCountString(last7.requests)) \(L("requests"))", .secondary)) entries.append(.text( "\(historyLabel): \(UsageFormatter.usdString(last30.costUSD)) · " + "\(UsageFormatter.tokenCountString(last30.requests)) \(L("requests"))", .secondary)) if let topModel = usage.topModels.first?.name { entries.append(.text("\(L("Top model")): \(topModel)", .secondary)) } } private static func appendClaudeAdminAPIUsageSummary( entries: inout [Entry], usage: ClaudeAdminAPIUsageSnapshot) { let today = usage.latestDay let last7 = usage.last7Days let last30 = usage.last30Days entries.append(.text( "\(L("Today")): \(UsageFormatter.usdString(today.costUSD)) · " + "\(UsageFormatter.tokenCountString(today.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "7d: \(UsageFormatter.usdString(last7.costUSD)) · " + "\(UsageFormatter.tokenCountString(last7.totalTokens)) \(L("tokens"))", .secondary)) entries.append(.text( "30d: \(UsageFormatter.usdString(last30.costUSD)) · " + "\(UsageFormatter.tokenCountString(last30.totalTokens)) \(L("tokens"))", .secondary)) if let topModel = usage.topModels.first?.name { entries.append(.text("\(L("Top model")): \(topModel)", .secondary)) } } private static func appendOpenRouterUsageSummary( entries: inout [Entry], usage: OpenRouterUsageSnapshot) { if let daily = usage.keyUsageDaily { entries.append(.text("\(L("Today")): \(UsageFormatter.usdString(daily))", .secondary)) } if let weekly = usage.keyUsageWeekly { entries.append(.text("\(L("Week")): \(UsageFormatter.usdString(weekly))", .secondary)) } if let monthly = usage.keyUsageMonthly { entries.append(.text("\(L("Month")): \(UsageFormatter.usdString(monthly))", .secondary)) } } private static func appendMistralUsageSummary( entries: inout [Entry], usage: MistralUsageSnapshot) { let latest = usage.daily.last if let latest { entries.append(.text( "\(L("Latest")): \(usage.currencySymbol)\(String(format: "%.4f", max(0, latest.cost))) · " + "\(UsageFormatter.tokenCountString(latest.totalTokens)) \(L("tokens"))", .secondary)) } let totalTokens = usage.totalInputTokens + usage.totalCachedTokens + usage.totalOutputTokens entries.append(.text( "\(L("Month")): \(usage.currencySymbol)\(String(format: "%.4f", max(0, usage.totalCost))) · " + "\(UsageFormatter.tokenCountString(totalTokens)) \(L("tokens"))", .secondary)) if let top = Self.topMistralModel(from: usage.daily) { entries.append(.text("\(L("Top model")): \(top)", .secondary)) } } private static func topMistralModel(from entries: [MistralDailyUsageBucket]) -> String? { var tokens: [String: Int] = [:] for entry in entries { for model in entry.models { tokens[model.name, default: 0] += model.totalTokens } } return tokens.max { if $0.value == $1.value { return $0.key > $1.key } return $0.value < $1.value }?.key } private static func appendPoeUsageSummary( entries: inout [Entry], usage: PoeUsageHistorySnapshot) { let today = usage.latestDay let week = usage.last7Days let month = usage.last30Days let todayCostSuffix = today.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" let weekCostSuffix = week.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" let monthCostSuffix = month.costUSD.map { " · \(UsageFormatter.usdString($0))" } ?? "" entries.append(.text( "\(L("Today")): \(Self.pointsString(today.points)) · " + "\(UsageFormatter.tokenCountString(today.requests)) \(L("requests"))\(todayCostSuffix)", .secondary)) entries.append(.text( "7d: \(Self.pointsString(week.points)) · " + "\(UsageFormatter.tokenCountString(week.requests)) \(L("requests"))\(weekCostSuffix)", .secondary)) entries.append(.text( "30d: \(Self.pointsString(month.points)) · " + "\(UsageFormatter.tokenCountString(month.requests)) \(L("requests"))\(monthCostSuffix)", .secondary)) if let topModel = usage.topModels.first { entries.append( .text( "\(L("Top model")): \(topModel.name) (\(Self.pointsString(topModel.points)))", .secondary)) } if !usage.topUsageTypes.isEmpty { let summary = usage.topUsageTypes .prefix(2) .map { "\($0.name): \(Self.pointsString($0.points))" } .joined(separator: " · ") entries.append(.text("Usage mix: \(summary)", .secondary)) } let recent = usage.recentEntries(limit: 3) if !recent.isEmpty { entries.append(.text("Recent activity:", .secondary)) for entry in recent { let stamp = Self.poeTimeString(entry.createdAt) entries.append(.text( "\(stamp) · \(entry.model) · \(Self.pointsString(entry.points))", .secondary)) } } } private static func pointsString(_ points: Double) -> String { let value = max(0, points) if value.rounded() == value { return "\(UsageFormatter.tokenCountString(Int(value))) points" } return "\(String(format: "%.1f", value)) points" } private static func poeTimeString(_ date: Date) -> String { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = .current formatter.dateFormat = "MM-dd HH:mm" return formatter.string(from: date) } private static func accountSection( for provider: UsageProvider, store: UsageStore, settings: SettingsStore, account: AccountInfo) -> Section? { let snapshot = store.snapshot(for: provider) let metadata = store.metadata(for: provider) let entries = Self.accountEntries( provider: provider, snapshot: snapshot, metadata: metadata, fallback: account, hidePersonalInfo: settings.hidePersonalInfo) guard !entries.isEmpty else { return nil } return Section(entries: entries) } private static func accountEntries( provider: UsageProvider, snapshot: UsageSnapshot?, metadata: ProviderMetadata, fallback: AccountInfo, hidePersonalInfo: Bool) -> [Entry] { var entries: [Entry] = [] let emailText = snapshot?.accountEmail(for: provider)? .trimmingCharacters(in: .whitespacesAndNewlines) let loginMethodText = snapshot?.loginMethod(for: provider)? .trimmingCharacters(in: .whitespacesAndNewlines) let redactedEmail = PersonalInfoRedactor.redactEmail(emailText, isEnabled: hidePersonalInfo) if let emailText, !emailText.isEmpty { entries.append(.text("\(L("Account")): \(redactedEmail)", .secondary)) } if provider == .kiro { if let plan = snapshot?.kiroUsage?.displayPlanName, !plan.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { entries.append(.text("\(L("Plan")): \(plan)", .secondary)) } if let loginMethodText, !loginMethodText.isEmpty { entries.append(.text("\(L("Auth")): \(loginMethodText)", .secondary)) } if let overages = snapshot?.kiroUsage?.overagesStatus, !overages.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { entries.append(.text("\(L("Overages")): \(overages)", .secondary)) } } else if provider == .kilo {