Peter Steinbergerfeat: enhance cli text outputa639c4210 months agoHistory
206 lines · 8.4 KB · Swift
RawDownload
import CodexBarCoreimport Foundation enum CLIRenderer {    private static let accentColor = "95"    private static let accentBoldColor = "1;95"    private static let subtleColor = "90"    private static let paceMinimumExpectedPercent: Double = 3    private static let usageBarWidth = 12     static func renderText(        provider: UsageProvider,        snapshot: UsageSnapshot,        credits: CreditsSnapshot?,        context: RenderContext) -> String    {        let meta = ProviderDescriptorRegistry.descriptor(for: provider).metadata        let now = Date()        var lines: [String] = []        lines.append(self.headerLine(context.header, useColor: context.useColor))         if let primary = snapshot.primary {            lines.append(self.rateLine(title: meta.sessionLabel, window: primary, useColor: context.useColor))            if let reset = self.resetLine(for: primary, style: context.resetStyle, now: now) {                lines.append(self.subtleLine(reset, useColor: context.useColor))            }        } else if let cost = snapshot.providerCost {            // Fallback to cost/quota display if no primary rate window            let label = cost.currencyCode == "Quota" ? "Quota" : "Cost"            let value = "\(String(format: "%.1f", cost.used)) / \(String(format: "%.1f", cost.limit))"            lines.append(self.labelValueLine(label, value: value, useColor: context.useColor))        }         if let weekly = snapshot.secondary {            lines.append(self.rateLine(title: meta.weeklyLabel, window: weekly, useColor: context.useColor))            if let pace = self.paceLine(provider: provider, window: weekly, useColor: context.useColor, now: now) {                lines.append(pace)            }            if let reset = self.resetLine(for: weekly, style: context.resetStyle, now: now) {                lines.append(self.subtleLine(reset, useColor: context.useColor))            }        }         if meta.supportsOpus, let opus = snapshot.tertiary {            lines.append(self.rateLine(title: meta.opusLabel ?? "Sonnet", window: opus, useColor: context.useColor))            if let reset = self.resetLine(for: opus, style: context.resetStyle, now: now) {                lines.append(self.subtleLine(reset, useColor: context.useColor))            }        }         if provider == .codex, let credits {            lines.append(self.labelValueLine(                "Credits",                value: UsageFormatter.creditsString(from: credits.remaining),                useColor: context.useColor))        }         if let email = snapshot.accountEmail(for: provider), !email.isEmpty {            lines.append(self.labelValueLine("Account", value: email, useColor: context.useColor))        }        if let plan = snapshot.loginMethod(for: provider), !plan.isEmpty {            lines.append(self.labelValueLine("Plan", value: plan.capitalized, useColor: context.useColor))        }         if let status = context.status {            let statusLine = "Status: \(status.indicator.label)\(status.descriptionSuffix)"            lines.append(self.colorize(statusLine, indicator: status.indicator, useColor: context.useColor))        }         return lines.joined(separator: "\n")    }     static func rateLine(title: String, window: RateWindow, useColor: Bool) -> String {        let text = UsageFormatter.usageLine(remaining: window.remainingPercent, used: window.usedPercent)        let colored = self.colorizeUsage(text, remainingPercent: window.remainingPercent, useColor: useColor)        let bar = self.usageBar(remainingPercent: window.remainingPercent, useColor: useColor)        return "\(title): \(colored) \(bar)"    }     private static func resetLine(for window: RateWindow, style: ResetTimeDisplayStyle, now: Date) -> String? {        UsageFormatter.resetLine(for: window, style: style, now: now)    }     private static func headerLine(_ header: String, useColor: Bool) -> String {        let decorated = "== \(header) =="        guard useColor else { return decorated }        return self.ansi(self.accentBoldColor, decorated)    }     private static func labelValueLine(_ label: String, value: String, useColor: Bool) -> String {        let labelText = self.label(label, useColor: useColor)        return "\(labelText): \(value)"    }     private static func label(_ text: String, useColor: Bool) -> String {        guard useColor else { return text }        return self.ansi(self.accentColor, text)    }     private static func subtleLine(_ text: String, useColor: Bool) -> String {        guard useColor else { return text }        return self.ansi(self.subtleColor, text)    }     private static func usageBar(remainingPercent: Double, useColor: Bool) -> String {        let clamped = max(0, min(100, remainingPercent))        let rawFilled = Int((clamped / 100) * Double(Self.usageBarWidth))        let filled = max(0, min(Self.usageBarWidth, rawFilled))        let empty = max(0, Self.usageBarWidth - filled)        let bar = "[\(String(repeating: "=", count: filled))\(String(repeating: "-", count: empty))]"        guard useColor else { return bar }        return self.ansi(self.accentColor, bar)    }     private static func paceLine(        provider: UsageProvider,        window: RateWindow,        useColor: Bool,        now: Date) -> String?    {        guard provider == .codex || provider == .claude else { return nil }        guard window.remainingPercent > 0 else { return nil }        guard let pace = UsagePace.weekly(window: window, now: now, defaultWindowMinutes: 10080) else { return nil }        guard pace.expectedUsedPercent >= Self.paceMinimumExpectedPercent else { return nil }         let expected = Int(pace.expectedUsedPercent.rounded())        var parts: [String] = []        parts.append(Self.paceLeftLabel(for: pace))        parts.append("Expected \(expected)% used")        if let rightLabel = Self.paceRightLabel(for: pace, now: now) {            parts.append(rightLabel)        }        let label = self.label("Pace", useColor: useColor)        return "\(label): \(parts.joined(separator: " | "))"    }     private static func paceLeftLabel(for pace: UsagePace) -> String {        let deltaValue = Int(abs(pace.deltaPercent).rounded())        switch pace.stage {        case .onTrack:            return "On pace"        case .slightlyAhead, .ahead, .farAhead:            return "\(deltaValue)% in deficit"        case .slightlyBehind, .behind, .farBehind:            return "\(deltaValue)% in reserve"        }    }     private static func paceRightLabel(for pace: UsagePace, now: Date) -> String? {        if pace.willLastToReset { return "Lasts until reset" }        guard let etaSeconds = pace.etaSeconds else { return nil }        let etaText = Self.paceDurationText(seconds: etaSeconds, now: now)        if etaText == "now" { return "Runs out now" }        return "Runs out in \(etaText)"    }     private static func paceDurationText(seconds: TimeInterval, now: Date) -> String {        let date = now.addingTimeInterval(seconds)        let countdown = UsageFormatter.resetCountdownDescription(from: date, now: now)        if countdown == "now" { return "now" }        if countdown.hasPrefix("in ") { return String(countdown.dropFirst(3)) }        return countdown    }     private static func colorizeUsage(_ text: String, remainingPercent: Double, useColor: Bool) -> String {        guard useColor else { return text }         let code = switch remainingPercent {        case ..<10:            "31" // red        case ..<25:            "33" // yellow        default:            "32" // green        }        return self.ansi(code, text)    }     private static func colorize(        _ text: String,        indicator: ProviderStatusPayload.ProviderStatusIndicator,        useColor: Bool)        -> String    {        guard useColor else { return text }        let code = switch indicator {        case .none: "32" // green        case .minor: "33" // yellow        case .major, .critical: "31" // red        case .maintenance: "34" // blue        case .unknown: "90" // gray        }        return self.ansi(code, text)    }     private static func ansi(_ code: String, _ text: String) -> String {        "\u{001B}[\(code)m\(text)\u{001B}[0m"    }} struct RenderContext {    let header: String    let status: ProviderStatusPayload?    let useColor: Bool    let resetStyle: ResetTimeDisplayStyle}