diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f62f31461..5e4fc4c0b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.36.2 — Unreleased ### Changed +- Antigravity: use current backend quota labels in menus and widgets while preferring a usable quota lane over an exhausted one. Thanks @Yuxin-Qiao! - Menu bar: reuse the icon-observation signature during provider refreshes instead of computing it twice. Thanks @abe238! - LiteLLM: show personal and team spend amounts directly on budget rows while suppressing duplicate budget sections. Thanks @hololee! diff --git a/Sources/CodexBar/MenuBarMetricWindowResolver.swift b/Sources/CodexBar/MenuBarMetricWindowResolver.swift index 779ba622bb..0ebde65466 100644 --- a/Sources/CodexBar/MenuBarMetricWindowResolver.swift +++ b/Sources/CodexBar/MenuBarMetricWindowResolver.swift @@ -146,6 +146,11 @@ enum MenuBarMetricWindowResolver { .filter { $0.usageKnown && $0.id.hasPrefix(Self.antigravityQuotaSummaryWindowIDPrefix) } .map(\.window) ?? [] guard !windows.isEmpty else { return nil } + + let usableWindows = windows.filter { $0.usedPercent < 100 } + if let maxUsable = usableWindows.max(by: { $0.usedPercent < $1.usedPercent }) { + return maxUsable + } return windows.max(by: { $0.usedPercent < $1.usedPercent }) } @@ -156,6 +161,11 @@ enum MenuBarMetricWindowResolver { } .map(\.window) ?? [] guard !windows.isEmpty else { return nil } + + let usableWindows = windows.filter { $0.usedPercent < 100 } + if let maxUsable = usableWindows.max(by: { $0.usedPercent < $1.usedPercent }) { + return maxUsable + } return windows.max(by: { $0.usedPercent < $1.usedPercent }) } diff --git a/Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift b/Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift index 6cab4e5e61..e606760196 100644 --- a/Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +++ b/Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift @@ -9,8 +9,8 @@ public enum AntigravityProviderDescriptor { metadata: ProviderMetadata( id: .antigravity, displayName: "Antigravity", - sessionLabel: "Gemini", - weeklyLabel: "Claude + GPT", + sessionLabel: "Gemini Models", + weeklyLabel: "Claude and GPT", opusLabel: nil, supportsOpus: false, supportsCredits: false, diff --git a/Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift b/Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift index a9ddf5c2ba..f833c0e66e 100644 --- a/Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift +++ b/Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift @@ -51,8 +51,8 @@ private enum AntigravityUsagePool: Hashable { var title: String { switch self { - case .gemini: "Gemini" - case .claudeGPT: "Claude + GPT" + case .gemini: "Gemini Models" + case .claudeGPT: "Claude and GPT models" } } @@ -207,8 +207,12 @@ public struct AntigravityStatusSnapshot: Sendable { throw AntigravityStatusProbeError.parseFailed("No quota buckets available") } - let primary = Self.quotaSummaryRepresentative(title: "Gemini", in: namedWindows) - let secondary = Self.quotaSummaryRepresentative(title: "Claude + GPT", in: namedWindows) + let primary = Self.quotaSummaryRepresentative( + matching: { $0.lowercased().contains("gemini") }, + in: namedWindows) + let secondary = Self.quotaSummaryRepresentative( + matching: { $0.lowercased().contains("claude") || $0.lowercased().contains("gpt") }, + in: namedWindows) let identity = ProviderIdentitySnapshot( providerID: .antigravity, @@ -225,11 +229,11 @@ public struct AntigravityStatusSnapshot: Sendable { } private static func quotaSummaryRepresentative( - title: String, + matching predicate: (String) -> Bool, in windows: [NamedRateWindow]) -> RateWindow? { windows - .filter { $0.usageKnown && $0.title.hasPrefix("\(title) ") } + .filter { $0.usageKnown && predicate($0.title) } .max { lhs, rhs in if lhs.window.usedPercent != rhs.window.usedPercent { return lhs.window.usedPercent < rhs.window.usedPercent @@ -295,29 +299,11 @@ public struct AntigravityStatusSnapshot: Sendable { private static func displayTitle(forQuotaGroup group: AntigravityQuotaSummaryGroup) -> String { let title = group.displayName.trimmingCharacters(in: .whitespacesAndNewlines) - let lower = title.lowercased() - if lower.contains("gemini") { - return "Gemini" - } - if lower.contains("claude") || lower.contains("gpt") { - return "Claude + GPT" - } - let stripped = title.replacingOccurrences( - of: #"(?i)\s+models?$"#, - with: "", - options: .regularExpression) - return stripped.isEmpty ? title : stripped + return title.isEmpty ? "Quota" : title } private static func displayTitle(forQuotaBucket bucket: AntigravityQuotaSummaryBucket) -> String { - switch self.quotaBucketKind(for: bucket) { - case .session: - "Session" - case .weekly: - "Weekly" - case .other: - bucket.displayName - } + bucket.displayName } private static func windowMinutes(forQuotaBucket bucket: AntigravityQuotaSummaryBucket) -> Int? { diff --git a/Sources/CodexBarWidget/CodexBarWidgetViews.swift b/Sources/CodexBarWidget/CodexBarWidgetViews.swift index 07a8e78c52..10fe0183fe 100644 --- a/Sources/CodexBarWidget/CodexBarWidgetViews.swift +++ b/Sources/CodexBarWidget/CodexBarWidgetViews.swift @@ -521,6 +521,11 @@ struct WidgetUsageRow: Identifiable, Equatable { let title: String let percentLeft: Double? + private enum AntigravityQuotaFamily { + case gemini + case claudeGPT + } + static func smallWidgetRowLimit(for entry: WidgetSnapshot.ProviderEntry) -> Int? { self.antigravityQuotaSummaryRowLimit(for: entry, limit: 2) } @@ -574,21 +579,10 @@ struct WidgetUsageRow: Identifiable, Equatable { limit >= 2, rows.contains(where: { $0.id.hasPrefix("antigravity-quota-summary-") }) { - var selected = ["Gemini ", "Claude + GPT "].compactMap { titlePrefix in + var selected = [AntigravityQuotaFamily.gemini, .claudeGPT].compactMap { family in rows - .filter { $0.title.hasPrefix(titlePrefix) } - .min { lhs, rhs in - switch (lhs.percentLeft, rhs.percentLeft) { - case let (.some(left), .some(right)): - left < right - case (.some, .none): - true - case (.none, .some): - false - case (.none, .none): - false - } - } + .filter { self.antigravityQuotaFamily(for: $0) == family } + .min(by: self.isMoreConstrained) } let selectedIDs = Set(selected.map(\.id)) let fallbackRows = rows.enumerated() @@ -611,6 +605,39 @@ struct WidgetUsageRow: Identifiable, Equatable { } return Array(rows.prefix(max(0, limit))) } + + private static func antigravityQuotaFamily(for row: WidgetUsageRow) -> AntigravityQuotaFamily? { + guard row.id.hasPrefix("antigravity-quota-summary-") else { return nil } + let id = row.id.lowercased() + if id.contains("gemini") { + return .gemini + } + if id.contains("3p") || id.contains("third-party") { + return .claudeGPT + } + + let title = row.title.lowercased() + if title.contains("gemini") { + return .gemini + } + if title.contains("claude") || title.contains("gpt") { + return .claudeGPT + } + return nil + } + + private static func isMoreConstrained(_ lhs: WidgetUsageRow, than rhs: WidgetUsageRow) -> Bool { + switch (lhs.percentLeft, rhs.percentLeft) { + case let (.some(left), .some(right)): + left < right + case (.some, .none): + true + case (.none, .some): + false + case (.none, .none): + false + } + } } private struct HistoryView: View { diff --git a/Tests/CodexBarTests/AntigravityQuotaSummaryTests.swift b/Tests/CodexBarTests/AntigravityQuotaSummaryTests.swift index 7d30de59a3..48824ad58b 100644 --- a/Tests/CodexBarTests/AntigravityQuotaSummaryTests.swift +++ b/Tests/CodexBarTests/AntigravityQuotaSummaryTests.swift @@ -37,10 +37,10 @@ struct AntigravityQuotaSummaryTests { "antigravity-quota-summary-3p-weekly", ]) #expect(windows.map(\.title) == [ - "Gemini Session", - "Gemini Weekly", - "Claude + GPT Session", - "Claude + GPT Weekly", + "Gemini Models Five Hour Limit", + "Gemini Models Weekly Limit", + "Claude and GPT models Five Hour Limit", + "Claude and GPT models Weekly Limit", ]) #expect(windows.map(\.window.windowMinutes) == [300, 10080, 300, 10080]) #expect(windows.map { $0.window.remainingPercent.rounded() } == [91, 82, 73, 64]) diff --git a/Tests/CodexBarTests/AntigravityStatusProbeTests.swift b/Tests/CodexBarTests/AntigravityStatusProbeTests.swift index 8ca8cda896..8567f7bf7e 100644 --- a/Tests/CodexBarTests/AntigravityStatusProbeTests.swift +++ b/Tests/CodexBarTests/AntigravityStatusProbeTests.swift @@ -1177,7 +1177,7 @@ extension AntigravityStatusProbeTests { #expect(usage.primary == nil) let modelWindow = try #require(usage.extraRateWindows?.first) #expect(modelWindow.id == "antigravity-gemini") - #expect(modelWindow.title == "Gemini") + #expect(modelWindow.title == "Gemini Models") #expect(modelWindow.window.resetsAt == resetTime) #expect(modelWindow.usageKnown == false) } diff --git a/Tests/CodexBarTests/CodexBarWidgetProviderTests.swift b/Tests/CodexBarTests/CodexBarWidgetProviderTests.swift index 190c3683f8..648ad48172 100644 --- a/Tests/CodexBarTests/CodexBarWidgetProviderTests.swift +++ b/Tests/CodexBarTests/CodexBarWidgetProviderTests.swift @@ -38,19 +38,19 @@ struct CodexBarWidgetProviderTests { usageRows: [ WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-gemini-session", - title: "Gemini Session", + title: "Gemini Models Five Hour Limit", percentLeft: 80), WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", percentLeft: 20), WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-third-party-session", - title: "Claude + GPT Session", + title: "Claude and GPT models Five Hour Limit", percentLeft: 5), WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-third-party-weekly", - title: "Claude + GPT Weekly", + title: "Claude and GPT models Weekly Limit", percentLeft: 60), ], creditsRemaining: nil, @@ -60,7 +60,7 @@ struct CodexBarWidgetProviderTests { let rows = WidgetUsageRow.rows(for: entry, limit: 2) - #expect(rows.map(\.title) == ["Gemini Weekly", "Claude + GPT Session"]) + #expect(rows.map(\.title) == ["Gemini Models Weekly Limit", "Claude and GPT models Five Hour Limit"]) #expect(rows.compactMap(\.percentLeft) == [20, 5]) #expect(WidgetUsageRow.smallWidgetRowLimit(for: entry) == 2) #expect(WidgetUsageRow.mediumWidgetRowLimit(for: entry) == 3) @@ -68,9 +68,48 @@ struct CodexBarWidgetProviderTests { for: entry, limit: WidgetUsageRow.mediumWidgetRowLimit(for: entry)) #expect(mediumRows.map(\.title) == [ - "Gemini Weekly", - "Claude + GPT Session", - "Claude + GPT Weekly", + "Gemini Models Weekly Limit", + "Claude and GPT models Five Hour Limit", + "Claude and GPT models Weekly Limit", + ]) + } + + @Test + func `small antigravity widget keeps claude gpt family when fallback rows are more constrained`() { + let entry = WidgetSnapshot.ProviderEntry( + provider: .antigravity, + updatedAt: Date(), + primary: nil, + secondary: nil, + tertiary: nil, + usageRows: [ + WidgetSnapshot.WidgetUsageRowSnapshot( + id: "antigravity-quota-summary-gemini-5h", + title: "Gemini Models Five Hour Limit", + percentLeft: 40), + WidgetSnapshot.WidgetUsageRowSnapshot( + id: "antigravity-quota-summary-gemini-weekly", + title: "Gemini Models Weekly Limit", + percentLeft: 70), + WidgetSnapshot.WidgetUsageRowSnapshot( + id: "antigravity-quota-summary-3p-5h", + title: "Claude and GPT models Five Hour Limit", + percentLeft: 60), + WidgetSnapshot.WidgetUsageRowSnapshot( + id: "antigravity-quota-summary-other-5h", + title: "Other Five Hour Limit", + percentLeft: 1), + ], + creditsRemaining: nil, + codeReviewRemainingPercent: nil, + tokenUsage: nil, + dailyUsage: []) + + let rows = WidgetUsageRow.rows(for: entry, limit: 2) + + #expect(rows.map(\.id) == [ + "antigravity-quota-summary-gemini-5h", + "antigravity-quota-summary-3p-5h", ]) } @@ -109,15 +148,15 @@ struct CodexBarWidgetProviderTests { usageRows: [ WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-gemini-session", - title: "Gemini Session", + title: "Gemini Models Five Hour Limit", percentLeft: nil), WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", percentLeft: 100), WidgetSnapshot.WidgetUsageRowSnapshot( id: "antigravity-quota-summary-third-party-session", - title: "Claude + GPT Session", + title: "Claude and GPT models Five Hour Limit", percentLeft: 80), ], creditsRemaining: nil, @@ -127,7 +166,7 @@ struct CodexBarWidgetProviderTests { let rows = WidgetUsageRow.rows(for: entry, limit: 2) - #expect(rows.map(\.title) == ["Gemini Weekly", "Claude + GPT Session"]) + #expect(rows.map(\.title) == ["Gemini Models Weekly Limit", "Claude and GPT models Five Hour Limit"]) } @Test @@ -305,7 +344,7 @@ struct CodexBarWidgetProviderTests { let rows = WidgetUsageRow.rows(for: entry) #expect(rows.map(\.id) == ["primary", "secondary"]) - #expect(rows.map(\.title) == ["Gemini", "Claude + GPT"]) + #expect(rows.map(\.title) == ["Gemini Models", "Claude and GPT"]) #expect(rows.compactMap(\.percentLeft) == [90, 80]) } diff --git a/Tests/CodexBarTests/MenuBarMetricWindowResolverTests.swift b/Tests/CodexBarTests/MenuBarMetricWindowResolverTests.swift index ea44c9a45d..96d56b0428 100644 --- a/Tests/CodexBarTests/MenuBarMetricWindowResolverTests.swift +++ b/Tests/CodexBarTests/MenuBarMetricWindowResolverTests.swift @@ -81,6 +81,41 @@ struct MenuBarMetricWindowResolverTests { #expect(window?.resetDescription == "Gemini Pro") } + @Test + func `automatic metric skips exhausted antigravity five hour bucket when another remains usable`() { + let snapshot = UsageSnapshot( + primary: RateWindow(usedPercent: 30, windowMinutes: 10080, resetsAt: nil, resetDescription: nil), + secondary: RateWindow(usedPercent: 67, windowMinutes: 10080, resetsAt: nil, resetDescription: nil), + extraRateWindows: [ + NamedRateWindow( + id: "antigravity-quota-summary-gemini-5h", + title: "Gemini Models Five Hour Limit", + window: RateWindow(usedPercent: 71, windowMinutes: 300, resetsAt: nil, resetDescription: nil)), + NamedRateWindow( + id: "antigravity-quota-summary-gemini-weekly", + title: "Gemini Models Weekly Limit", + window: RateWindow(usedPercent: 30, windowMinutes: 10080, resetsAt: nil, resetDescription: nil)), + NamedRateWindow( + id: "antigravity-quota-summary-3p-5h", + title: "Claude and GPT models Five Hour Limit", + window: RateWindow(usedPercent: 100, windowMinutes: 300, resetsAt: nil, resetDescription: nil)), + NamedRateWindow( + id: "antigravity-quota-summary-3p-weekly", + title: "Claude and GPT models Weekly Limit", + window: RateWindow(usedPercent: 67, windowMinutes: 10080, resetsAt: nil, resetDescription: nil)), + ], + updatedAt: Date()) + + let window = MenuBarMetricWindowResolver.rateWindow( + preference: .automatic, + provider: .antigravity, + snapshot: snapshot, + supportsAverage: false) + + #expect(window?.remainingPercent == 29) + #expect(window?.windowMinutes == 300) + } + @Test func `automatic metric uses recognized antigravity gemini pool when claude gpt is reset only`() throws { let resetOnlyReset = Date(timeIntervalSince1970: 1000) diff --git a/Tests/CodexBarTests/MenuCardAntigravityTests.swift b/Tests/CodexBarTests/MenuCardAntigravityTests.swift index b8d5b8b003..28895f7dc7 100644 --- a/Tests/CodexBarTests/MenuCardAntigravityTests.swift +++ b/Tests/CodexBarTests/MenuCardAntigravityTests.swift @@ -45,7 +45,7 @@ struct MenuCardAntigravityTests { now: now)) #expect(model.metrics.count == 1) - #expect(model.metrics.map(\.title) == ["Gemini"]) + #expect(model.metrics.map(\.title) == ["Gemini Models"]) #expect(model.metrics[0].percent == 95) #expect(model.metrics[0].percentLabel == "95% left") } @@ -100,7 +100,7 @@ struct MenuCardAntigravityTests { hidePersonalInfo: false, now: now)) - #expect(model.metrics.map(\.title) == ["Gemini", "Claude + GPT"]) + #expect(model.metrics.map(\.title) == ["Gemini Models", "Claude and GPT"]) #expect(!model.metrics.contains { $0.title == "Gemini 3.1 Pro (Low)" }) } @@ -162,8 +162,8 @@ struct MenuCardAntigravityTests { now: now)) #expect(model.metrics.map(\.title) == [ - "Gemini", - "Claude + GPT", + "Gemini Models", + "Claude and GPT", ]) #expect(model.metrics.map(\.percentLabel) == [ "50% left", @@ -219,7 +219,7 @@ struct MenuCardAntigravityTests { // Distinct extra windows remain visible even with optional extras disabled. #expect(model.metrics.contains { $0.title == "Experimental Tool" }) - #expect(model.metrics.contains { $0.title == "Gemini" }) + #expect(model.metrics.contains { $0.title == "Gemini Models" }) } @Test @@ -240,7 +240,7 @@ struct MenuCardAntigravityTests { extraRateWindows: [ NamedRateWindow( id: "antigravity-quota-summary-gemini-5h", - title: "Gemini Session", + title: "Gemini Models Five Hour Limit", window: RateWindow( usedPercent: 9, windowMinutes: 300, @@ -249,7 +249,7 @@ struct MenuCardAntigravityTests { + "4 hours.")), NamedRateWindow( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", window: RateWindow( usedPercent: 18, windowMinutes: 10080, @@ -257,7 +257,7 @@ struct MenuCardAntigravityTests { resetDescription: "You have used some of your weekly limit, it will fully refresh in 5 days.")), NamedRateWindow( id: "antigravity-quota-summary-3p-5h", - title: "Claude + GPT Session", + title: "Claude and GPT models Five Hour Limit", window: RateWindow( usedPercent: 27, windowMinutes: 300, @@ -266,7 +266,7 @@ struct MenuCardAntigravityTests { + "3 hours.")), NamedRateWindow( id: "antigravity-quota-summary-3p-weekly", - title: "Claude + GPT Weekly", + title: "Claude and GPT models Weekly Limit", window: RateWindow( usedPercent: 36, windowMinutes: 10080, @@ -308,10 +308,10 @@ struct MenuCardAntigravityTests { "antigravity-quota-summary-3p-weekly", ]) #expect(model.metrics.map(\.title) == [ - "Gemini Session", - "Gemini Weekly", - "Claude + GPT Session", - "Claude + GPT Weekly", + "Gemini Models Five Hour Limit", + "Gemini Models Weekly Limit", + "Claude and GPT models Five Hour Limit", + "Claude and GPT models Weekly Limit", ]) #expect(model.metrics.map(\.percentLabel) == [ "91% left", @@ -363,7 +363,7 @@ struct MenuCardAntigravityTests { now: now)) #expect(model.metrics.count == 1) - #expect(model.metrics[0].title == "Gemini") + #expect(model.metrics[0].title == "Gemini Models") #expect(model.metrics[0].percent == 5) #expect(model.metrics[0].percentLabel == "5% used") } diff --git a/Tests/CodexBarTests/UsageStorePlanUtilizationTests.swift b/Tests/CodexBarTests/UsageStorePlanUtilizationTests.swift index 7e30824848..d8f9671455 100644 --- a/Tests/CodexBarTests/UsageStorePlanUtilizationTests.swift +++ b/Tests/CodexBarTests/UsageStorePlanUtilizationTests.swift @@ -861,7 +861,7 @@ struct UsageStorePlanUtilizationTests { extraRateWindows: [ NamedRateWindow( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", window: RateWindow( usedPercent: geminiWeeklyUsed, windowMinutes: 10080, @@ -869,7 +869,7 @@ struct UsageStorePlanUtilizationTests { resetDescription: nil)), NamedRateWindow( id: "antigravity-quota-summary-3p-weekly", - title: "Claude + GPT Weekly", + title: "Claude and GPT models Weekly Limit", window: RateWindow( usedPercent: thirdPartyWeeklyUsed, windowMinutes: 10080, diff --git a/Tests/CodexBarTests/UsageStoreSessionQuotaTransitionTests.swift b/Tests/CodexBarTests/UsageStoreSessionQuotaTransitionTests.swift index 1f46580367..f6edec7618 100644 --- a/Tests/CodexBarTests/UsageStoreSessionQuotaTransitionTests.swift +++ b/Tests/CodexBarTests/UsageStoreSessionQuotaTransitionTests.swift @@ -828,7 +828,7 @@ struct UsageStoreSessionQuotaTransitionTests { extraRateWindows: [ NamedRateWindow( id: "antigravity-quota-summary-gemini-5h", - title: "Gemini Session", + title: "Gemini Models Five Hour Limit", window: RateWindow( usedPercent: sessionUsed, windowMinutes: 5 * 60, @@ -836,7 +836,7 @@ struct UsageStoreSessionQuotaTransitionTests { resetDescription: nil)), NamedRateWindow( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", window: RateWindow( usedPercent: weeklyUsed, windowMinutes: 7 * 24 * 60, diff --git a/Tests/CodexBarTests/UsageStoreWidgetSnapshotTests.swift b/Tests/CodexBarTests/UsageStoreWidgetSnapshotTests.swift index 115940b056..53170ec374 100644 --- a/Tests/CodexBarTests/UsageStoreWidgetSnapshotTests.swift +++ b/Tests/CodexBarTests/UsageStoreWidgetSnapshotTests.swift @@ -44,7 +44,7 @@ struct UsageStoreWidgetSnapshotTests { let entry = try #require(widgetSnapshots.last?.entries.first { $0.provider == .antigravity }) #expect(entry.usageRows?.map(\.id) == ["primary", "secondary"]) - #expect(entry.usageRows?.map(\.title) == ["Gemini", "Claude + GPT"]) + #expect(entry.usageRows?.map(\.title) == ["Gemini Models", "Claude and GPT"]) #expect(entry.usageRows?.compactMap(\.percentLeft) == [90, 80]) } @@ -72,19 +72,19 @@ struct UsageStoreWidgetSnapshotTests { extraRateWindows: [ NamedRateWindow( id: "antigravity-quota-summary-gemini-5h", - title: "Gemini Session", + title: "Gemini Models Five Hour Limit", window: RateWindow(usedPercent: 9, windowMinutes: 300, resetsAt: nil, resetDescription: nil)), NamedRateWindow( id: "antigravity-quota-summary-gemini-weekly", - title: "Gemini Weekly", + title: "Gemini Models Weekly Limit", window: RateWindow(usedPercent: 18, windowMinutes: 10080, resetsAt: nil, resetDescription: nil)), NamedRateWindow( id: "antigravity-quota-summary-3p-5h", - title: "Claude + GPT Session", + title: "Claude and GPT models Five Hour Limit", window: RateWindow(usedPercent: 27, windowMinutes: 300, resetsAt: nil, resetDescription: nil)), NamedRateWindow( id: "antigravity-quota-summary-3p-weekly", - title: "Claude + GPT Weekly", + title: "Claude and GPT models Weekly Limit", window: RateWindow(usedPercent: 36, windowMinutes: 10080, resetsAt: nil, resetDescription: nil)), ], updatedAt: Date(), @@ -105,10 +105,10 @@ struct UsageStoreWidgetSnapshotTests { let entry = try #require(widgetSnapshots.last?.entries.first { $0.provider == .antigravity }) #expect(entry.usageRows?.map(\.title) == [ - "Gemini Session", - "Gemini Weekly", - "Claude + GPT Session", - "Claude + GPT Weekly", + "Gemini Models Five Hour Limit", + "Gemini Models Weekly Limit", + "Claude and GPT models Five Hour Limit", + "Claude and GPT models Weekly Limit", ]) #expect(entry.usageRows?.compactMap(\.percentLeft) == [91, 82, 73, 64]) } diff --git a/TestsLinux/AntigravityProcessLauncherLinuxTests.swift b/TestsLinux/AntigravityProcessLauncherLinuxTests.swift index 676be2f4db..417a7f8db2 100644 --- a/TestsLinux/AntigravityProcessLauncherLinuxTests.swift +++ b/TestsLinux/AntigravityProcessLauncherLinuxTests.swift @@ -36,7 +36,8 @@ struct AntigravityProcessLauncherLinuxTests { echo closed >> \(outputURL.path) fi """ - // Direct writes close the executable before spawn; atomic replacement can race with exec on overlay filesystems. + // Direct writes close the executable before spawn; atomic replacement can race with exec on overlay + // filesystems. try Data(script.utf8).write(to: scriptURL) #expect(chmod(scriptURL.path, 0o700) == 0)