import CodexBarCoreimport Commanderimport Foundation struct UsageCommandContext { let format: OutputFormat let includeCredits: Bool let sourceMode: ProviderSourceMode let antigravityPlanDebug: Bool let augmentDebug: Bool let webDebugDumpHTML: Bool let webTimeout: TimeInterval let verbose: Bool let useColor: Bool let resetStyle: ResetTimeDisplayStyle let fetcher: UsageFetcher let claudeFetcher: ClaudeUsageFetcher let browserDetection: BrowserDetection} struct UsageCommandOutput { var sections: [String] = [] var payload: [ProviderPayload] = [] var exitCode: ExitCode = .success} extension CodexBarCLI { static func fetchUsageOutputs( provider: UsageProvider, status: ProviderStatusPayload?, tokenContext: TokenAccountCLIContext, command: UsageCommandContext) async -> UsageCommandOutput { var output = UsageCommandOutput() let accounts: [ProviderTokenAccount] do { accounts = try tokenContext.resolvedAccounts(for: provider) } catch { Self.exit(code: .failure, message: "Error: \(error.localizedDescription)") } let accountSelections: [ProviderTokenAccount?] = accounts.isEmpty ? [nil] : accounts.map { Optional($0) } for account in accountSelections { var antigravityPlanInfo: AntigravityPlanInfoSummary? let env = tokenContext.environment( base: ProcessInfo.processInfo.environment, provider: provider, account: account) let settings = tokenContext.settingsSnapshot(for: provider, account: account) let effectiveSourceMode = tokenContext.effectiveSourceMode( base: command.sourceMode, provider: provider, account: account) let fetchContext = ProviderFetchContext( runtime: .cli, sourceMode: effectiveSourceMode, includeCredits: command.includeCredits, webTimeout: command.webTimeout, webDebugDumpHTML: command.webDebugDumpHTML, verbose: command.verbose, env: env, settings: settings, fetcher: command.fetcher, claudeFetcher: command.claudeFetcher, browserDetection: command.browserDetection) let outcome = await Self.fetchProviderUsage( provider: provider, context: fetchContext) if command.verbose { Self.printFetchAttempts(provider: provider, attempts: outcome.attempts) } switch outcome.result { case let .success(result): var dashboard = result.dashboard if command.antigravityPlanDebug, provider == .antigravity { antigravityPlanInfo = try? await AntigravityStatusProbe().fetchPlanInfoSummary() if command.format == .text, let info = antigravityPlanInfo { Self.printAntigravityPlanInfo(info) } } if command.augmentDebug, provider == .augment { #if os(macOS) let dump = await AugmentStatusProbe.latestDumps() if command.format == .text, !dump.isEmpty { Self.writeStderr("Augment API responses:\n\(dump)\n") } #endif } var usage = result.usage.scoped(to: provider) if let account { usage = tokenContext.applyAccountLabel(usage, provider: provider, account: account) } if dashboard == nil, command.format == .json, provider == .codex { dashboard = Self.loadOpenAIDashboardIfAvailable(usage: usage, fetcher: command.fetcher) } let descriptor = ProviderDescriptorRegistry.descriptor(for: provider) let shouldDetectVersion = descriptor.cli.versionDetector != nil && result.strategyKind != ProviderFetchKind.webDashboard let version = Self.normalizeVersion( raw: shouldDetectVersion ? Self.detectVersion(for: provider, browserDetection: command.browserDetection) : nil) let source = result.sourceLabel let header = Self.makeHeader(provider: provider, version: version, source: source) switch command.format { case .text: var text = CLIRenderer.renderText( provider: provider, snapshot: usage, credits: result.credits, context: RenderContext( header: header, status: status, useColor: command.useColor, resetStyle: command.resetStyle)) if let dashboard, provider == .codex, command.sourceMode.usesWeb { text += "\n" + Self.renderOpenAIWebDashboardText(dashboard) } output.sections.append(text) case .json: output.payload.append(ProviderPayload( provider: provider, account: account?.label, version: version, source: source, status: status, usage: usage, credits: result.credits, antigravityPlanInfo: antigravityPlanInfo, openaiDashboard: dashboard)) } case let .failure(error): output.exitCode = Self.mapError(error) if let account { Self.writeStderr("Error (\(provider.rawValue) - \(account.label)): \(error.localizedDescription)\n") } else { Self.printError(error) } } } return output }}
import CodexBarCore
import Commander
import Foundation
struct UsageCommandContext {
let format: OutputFormat
let includeCredits: Bool
let sourceMode: ProviderSourceMode
let antigravityPlanDebug: Bool
let augmentDebug: Bool
let webDebugDumpHTML: Bool
let webTimeout: TimeInterval
let verbose: Bool
let useColor: Bool
let resetStyle: ResetTimeDisplayStyle
let fetcher: UsageFetcher
let claudeFetcher: ClaudeUsageFetcher
let browserDetection: BrowserDetection
}
struct UsageCommandOutput {
var sections: [String] = []
var payload: [ProviderPayload] = []
var exitCode: ExitCode = .success
}
extension CodexBarCLI {
static func fetchUsageOutputs(
provider: UsageProvider,
status: ProviderStatusPayload?,
tokenContext: TokenAccountCLIContext,
command: UsageCommandContext) async -> UsageCommandOutput
{
var output = UsageCommandOutput()
let accounts: [ProviderTokenAccount]
do {
accounts = try tokenContext.resolvedAccounts(for: provider)
} catch {
Self.exit(code: .failure, message: "Error: \(error.localizedDescription)")
}
let accountSelections: [ProviderTokenAccount?] = accounts.isEmpty
? [nil]
: accounts.map { Optional($0) }
for account in accountSelections {
var antigravityPlanInfo: AntigravityPlanInfoSummary?
let env = tokenContext.environment(
base: ProcessInfo.processInfo.environment,
provider: provider,
account: account)
let settings = tokenContext.settingsSnapshot(for: provider, account: account)
let effectiveSourceMode = tokenContext.effectiveSourceMode(
base: command.sourceMode,
provider: provider,
account: account)
let fetchContext = ProviderFetchContext(
runtime: .cli,
sourceMode: effectiveSourceMode,
includeCredits: command.includeCredits,
webTimeout: command.webTimeout,
webDebugDumpHTML: command.webDebugDumpHTML,
verbose: command.verbose,
env: env,
settings: settings,
fetcher: command.fetcher,
claudeFetcher: command.claudeFetcher,
browserDetection: command.browserDetection)
let outcome = await Self.fetchProviderUsage(
provider: provider,
context: fetchContext)
if command.verbose {
Self.printFetchAttempts(provider: provider, attempts: outcome.attempts)
}
switch outcome.result {
case let .success(result):
var dashboard = result.dashboard
if command.antigravityPlanDebug, provider == .antigravity {
antigravityPlanInfo = try? await AntigravityStatusProbe().fetchPlanInfoSummary()
if command.format == .text, let info = antigravityPlanInfo {
Self.printAntigravityPlanInfo(info)
}
}
if command.augmentDebug, provider == .augment {
#if os(macOS)
let dump = await AugmentStatusProbe.latestDumps()
if command.format == .text, !dump.isEmpty {
Self.writeStderr("Augment API responses:\n\(dump)\n")
}
#endif
}
var usage = result.usage.scoped(to: provider)
if let account {
usage = tokenContext.applyAccountLabel(usage, provider: provider, account: account)
}
if dashboard == nil, command.format == .json, provider == .codex {
dashboard = Self.loadOpenAIDashboardIfAvailable(usage: usage, fetcher: command.fetcher)
}
let descriptor = ProviderDescriptorRegistry.descriptor(for: provider)
let shouldDetectVersion = descriptor.cli.versionDetector != nil
&& result.strategyKind != ProviderFetchKind.webDashboard
let version = Self.normalizeVersion(
raw: shouldDetectVersion
? Self.detectVersion(for: provider, browserDetection: command.browserDetection)
: nil)
let source = result.sourceLabel
let header = Self.makeHeader(provider: provider, version: version, source: source)
switch command.format {
case .text:
var text = CLIRenderer.renderText(
provider: provider,
snapshot: usage,
credits: result.credits,
context: RenderContext(
header: header,
status: status,
useColor: command.useColor,
resetStyle: command.resetStyle))
if let dashboard, provider == .codex, command.sourceMode.usesWeb {
text += "\n" + Self.renderOpenAIWebDashboardText(dashboard)
}
output.sections.append(text)
case .json:
output.payload.append(ProviderPayload(
provider: provider,
account: account?.label,
version: version,
source: source,
status: status,
usage: usage,
credits: result.credits,
antigravityPlanInfo: antigravityPlanInfo,
openaiDashboard: dashboard))
}
case let .failure(error):
output.exitCode = Self.mapError(error)
if let account {
Self.writeStderr("Error (\(provider.rawValue) - \(account.label)): \(error.localizedDescription)\n")
} else {
Self.printError(error)
}
}
}
return output
}
}