Skip to content

Fix automatic quota display priority for exhausted windows & Antigravity session preference#2352

Open
Yuxin-Qiao wants to merge 7 commits into
steipete:mainfrom
Yuxin-Qiao:fix/exhausted-quota-display-priority
Open

Fix automatic quota display priority for exhausted windows & Antigravity session preference#2352
Yuxin-Qiao wants to merge 7 commits into
steipete:mainfrom
Yuxin-Qiao:fix/exhausted-quota-display-priority

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Fix automatic quota display priority for exhausted windows & Simplify Antigravity to Gemini-only

Problem

1. Exhausted Quota Display (all default-path providers)

When a provider has multiple quota windows (e.g., weekly + 5-hour rate limit), the menu bar should display the exhausted window when any quota is used up. Instead, the default resolution logic (snapshot.primary ?? snapshot.secondary) blindly returned the primary window if it existed, hiding an exhausted secondary window from the user.

Example: Kimi's weekly quota is exhausted (0% remaining), but the menu bar still shows the 5-hour rate limit (96% remaining), misleading users into thinking they can still use the service.

2. Antigravity Quota Display Complexity

Previously, Antigravity attempted to merge, rank, and prioritize multiple distinct quota families (Gemini, Claude, GPT) across different cadences (5-hour session, weekly) within the unified menu bar icon and text.
This resulted in over 1,000 lines of complex special-case logic that:

  • Made the display jump around between Gemini and Claude.
  • Caused mismatches between the icon progress meters and menu text.
  • Confused users (e.g. showing Claude weekly quota at 30% when the active model was Gemini).
  • Exposed extremely low/restrictive GPT/Claude pools (which run out in a few messages anyway) to the main menu bar rotation.

Solution

Commit 1-3: Base fixes

  • Fix default-path exhausted window priority: Prioritize any exhausted window (usedPercent >= 100) first, then fall back to snapshot.primary ?? snapshot.secondary. Custom overrides for Kimi/Factory/LiteLLM, Copilot, and MiniMax are fully preserved.
  • Fix locale-dependent test failures: Modified UsagePaceText.swift to use codexBarLocalizedLocale() instead of implicit Locale.current.
  • Prefer session windows: Prefer session windows over weekly windows in automatic mode.

Commit 4-5: Simplify Antigravity to Gemini-Only

We realized that trying to merge multiple different model families in the menu bar was over-engineering. Users primarily use Antigravity for Gemini (the Claude/GPT quota is tiny and runs out instantly).

Thus, we made a major simplification:

  1. Gemini-Only in Menu Bar: Antigravity's menu bar status (icon + text) now only tracks Gemini's quota (primary = Gemini 5-hour, secondary = Gemini weekly).
  2. Claude/GPT remains visible in Menu Card: All Claude/GPT detailed windows are still fully parsed and visible in the slide-down menu card (as extraRateWindows), so the user does not lose visibility.
  3. Massive Code Deletion: Removed over 1,100 lines of custom, complex Antigravity quota-summary merging, ranking, family-blocking, and settings-toggle logic.
  4. Default Path Alignment: Antigravity now resolves automatically using the exact same standard default-path resolver logic as other providers (exhausted-first, then primary ?? secondary).

This significantly reduces maintenance overhead and makes the menu bar behavior predictable and robust.

Provider Audit

Providers affected by default-path fix

Provider Primary Secondary Tertiary Previously hid exhausted?
Codex Session Weekly
OpenCode Rolling (5h) Weekly
Alibaba CodingPlan 5-hour Weekly Monthly
ClinePass 5-hour Weekly Monthly
Doubao (coding plan) Session/5h Weekly Monthly
OpenCodeGo Rolling (5h) Weekly Monthly
Devin Daily Weekly
StepFun (rate plans) 5-hour Weekly
Sakana 5-hour Weekly
T3Chat 4-hour base Overage
Codebuff Credits Weekly
LongCat Total quota Fuel pack
Manus Monthly Refresh
Groq req/min tok/min cache/min

Providers NOT affected (custom overrides preserved)

Provider Override Logic
Antigravity Maps primary (Gemini 5h) and secondary (Gemini weekly) and uses default path
Perplexity automaticPerplexityWindow()
Zai Custom primary/tertiary swap
Kimi/Factory/LiteLLM Rate-limit default, exhausted-first
Copilot Max of primary/secondary
Cursor Custom three-way cursor logic
MiniMax Three-way mostConstrainedWindow
Claude Spend-limit override

Verification Evidence

make test — 673/673 tests passed, 0 failures ✅

✔ Suite MenuBarMetricWindowResolverTests passed after 0.002 seconds.
✔ Suite UsageStoreHighestUsageTests passed after 0.125 seconds.
✔ Suite LocalizationLanguageCatalogTests passed after 0.473 seconds.
✔ Test run with 673 tests in 1 suite passed after 71.9 seconds.

make check — 0 violations ✅

Running SwiftFormat...
SwiftFormat completed in 1.07s.
0/1578 files formatted.
Done linting! Found 0 violations, 0 serious in 1578 files.

Files changed

  • Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift — Directly maps Gemini 5-hour to primary and Gemini weekly to secondary.
  • Sources/CodexBar/IconRemainingResolver.swift — Reverted custom Antigravity code and signature modifications.
  • Sources/CodexBar/MenuBarMetricWindowResolver.swift — Removed all complex custom Antigravity ranking and helper methods.
  • Sources/CodexBar/UsageStore+HighestUsage.swift — Reverted all custom Antigravity automatic metrics checks and static helpers.
  • Tests/CodexBarTests/MenuBarMetricWindowResolverTests.swift & Tests/CodexBarTests/UsageStoreHighestUsageTests.swift & Tests/CodexBarTests/CodexbarTests.swift — Cleaned up obsolete Antigravity tests and added standard Gemini session vs weekly checks.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Jul 20, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 39bcea869d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +153 to +156
return self.mostConstrainedWindow(
primary: snapshot.primary,
secondary: snapshot.secondary,
tertiary: snapshot.tertiary)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep partially exhausted providers rankable

When this returns an exhausted lane for default multi-window providers (for example Kimi weekly at 100% with the 5-hour lane still active, or LiteLLM personal at 100% with team budget still active), the merged "show highest usage" path calls this resolver in UsageStore+HighestUsage.swift:55 and then shouldExcludeFromHighestUsage drops any non-special provider with metricPercent >= 100 by falling through to return true at lines 71-126. That means the exact exhausted quota this change is meant to surface is hidden from the unified icon/rotation unless all lanes are exhausted; add all-lanes-exhausted handling for the newly generalized providers or avoid feeding partial 100% windows into that exclusion path.

Useful? React with 👍 / 👎.

Comment on lines +42 to +44
let numberText = String(
format: L("≈%d full 5h windows of weekly left · %d windows until reset"),
locale: codexBarLocalizedLocale(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep stringsdict plural formatting intact

These strings are backed by Localizable.stringsdict entries with %#@...@ plural variables (en.lproj/Localizable.stringsdict:5-45). String.localizedStringWithFormat is the plural-aware path that expands those stringsdict variants; replacing it with plain String(format:locale:) no longer applies the singular/plural selections, so forecasts like 1 window regress from the expected singular text in SessionEquivalentForecastTests.swift:292-293 and localized plural forms are lost. Use a plural-aware formatting path while still controlling the app locale.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 20, 2026
@clawsweeper

clawsweeper Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 20, 2026, 9:29 AM ET / 13:29 UTC.

Summary
The branch prioritizes exhausted automatic quota windows, changes Antigravity menu-bar selection to Gemini session/weekly quotas, and adds a stored-layout Pace % token with localization updates.

Reproducibility: yes. from source inspection: construct a provider with an exhausted selected lane and another usable lane to reproduce the highest-usage exclusion, or migrate a legacy Pace layout for a snapshot without weekly pace to observe the unavailable placeholder.

Review metrics: 2 noteworthy metrics.

  • Change surface: 40 files affected; 324 added, 998 removed. The branch combines resolver behavior, provider presentation, persisted layout migration, and localization changes, so compatibility needs review beyond the central bug fix.
  • Proof supplied: 0 reviewed runtime captures. The body contains test and lint output but does not show the changed menu-bar behavior in a real freshly built app.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve the highest-usage, Pace fallback/refresh, and Antigravity fallback findings with focused tests.
  • Obtain maintainer direction for the Antigravity user-facing quota contract.
  • [P1] Add a redacted freshly built app capture or runtime transcript showing exhausted selection, Antigravity output, and Pace % behavior; update the PR body afterward.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides make test and make check transcript, but no redacted after-fix run demonstrates exhausted-window selection, Antigravity menu-bar output, or the Pace % layout in a freshly built app; add runtime proof and update the body for automatic re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Existing users can lose a visible usable provider in merged/highest-usage mode when one quota lane is exhausted but another remains usable.
  • [P2] Migrated legacy Pace layouts can replace the prior quota-percent fallback with an unavailable placeholder and can remain stale when pace changes.
  • [P2] The Gemini-only Antigravity choice changes established quota-family semantics without fully migrating labels, automatic fallback behavior, and user-facing expectations.

Maintainer options:

  1. Repair compatibility before merge (recommended)
    Restore partially exhausted providers in highest-usage selection, retain the legacy Pace fallback and refresh path, and add focused regression coverage for each.
  2. Choose and complete the Antigravity contract
    A product owner can approve Gemini-only status, but the branch must then migrate labels, compact fallback behavior, tests, and upgrade expectations consistently.
  3. Pause the scope reduction
    Keep the exhausted-window bug fix separate and defer the Antigravity contract change until the intended menu-bar semantics are agreed.

Next step before merge

  • [P1] A maintainer must choose the Antigravity contract, and the contributor must provide real behavior proof before normal merge review can complete.

Maintainer decision needed

  • Question: Should Antigravity’s menu bar permanently represent only Gemini session/weekly quotas, or should it continue to summarize the most constrained Gemini/Claude/GPT quota families?
  • Rationale: Both behaviors are plausible, but they expose different user-facing quota contracts and require different labels, fallbacks, tests, and upgrade expectations; source review cannot safely choose that product policy.
  • Likely owner: steipete — The unresolved choice is a repository-level product and compatibility contract for a provider surface.
  • Options:
    • Preserve the multi-family contract (recommended): Restore the existing Gemini/Claude/GPT summary behavior and apply the exhausted-window fix without narrowing the provider’s menu-bar scope.
    • Approve Gemini-only menu bar status: Keep Gemini session/weekly as the menu-bar contract, explicitly migrate all related labels and automatic fallbacks, and document that Claude/GPT remain card-only details.

Security
Cleared: The reviewed diff changes Swift application logic, resources, and tests without adding dependencies, workflow changes, downloaded code, expanded permissions, or credential handling.

Review findings

  • [P1] Keep partially exhausted providers eligible for highest usage — Sources/CodexBar/MenuBarMetricWindowResolver.swift:140
  • [P2] Preserve the legacy Pace percent fallback — Sources/CodexBar/MenuBarLayout.swift:221
  • [P2] Refresh custom Pace % layouts when pace changes — Sources/CodexBar/StatusItemController+MenuBarLayout.swift:57-79
Review details

Best possible solution:

Preserve compatibility for existing quota layouts and highest-usage selection, then land either a fully migrated Gemini-only Antigravity contract or the existing multi-family contract after the product owner chooses it and the contributor provides redacted runtime proof from a freshly built app.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: construct a provider with an exhausted selected lane and another usable lane to reproduce the highest-usage exclusion, or migrate a legacy Pace layout for a snapshot without weekly pace to observe the unavailable placeholder.

Is this the best way to solve the issue?

No, not yet: exhausted-window priority is a reasonable fix, but it must preserve merged-provider eligibility and legacy layout fallback behavior, while the Gemini-only Antigravity scope requires an explicit product decision.

Full review comments:

  • [P1] Keep partially exhausted providers eligible for highest usage — Sources/CodexBar/MenuBarMetricWindowResolver.swift:140
    Selecting an exhausted automatic lane now feeds a 100% metric into highest-usage filtering, but the generic exclusion path still removes the provider unless every lane is exhausted. This hides exactly the partially exhausted provider the resolver is meant to surface; retain it until all relevant lanes are blocked.
    Confidence: 0.95
  • [P2] Preserve the legacy Pace percent fallback — Sources/CodexBar/MenuBarLayout.swift:221
    Migrated legacy Pace layouts use .pacePercent, but runtime data is nil when weeklyPace cannot be computed. Those users previously received the selected quota percent, whereas the migrated layout renders an unavailable placeholder; preserve that fallback in the stored-layout path.
    Confidence: 0.94
  • [P2] Refresh custom Pace % layouts when pace changes — Sources/CodexBar/StatusItemController+MenuBarLayout.swift:57-79
    The new token depends on weekly pace, but the stored-layout observation signature still does not include the rendered Pace % value. A custom layout can therefore retain an old pace value until another signed field changes; sign the layout pace output or an equivalent revision.
    Confidence: 0.9
  • [P2] Align Antigravity labels with the new Gemini lanes — Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift:208-218
    The probe now assigns Gemini five-hour and weekly quotas to the primary and secondary lanes, while the established secondary presentation identifies Claude/GPT. Either retain the family mapping or migrate every visible label and associated behavior so Gemini weekly is not presented as Claude/GPT quota.
    Confidence: 0.95
  • [P2] Retain Antigravity compact fallback in Automatic — Sources/CodexBar/MenuBarMetricWindowResolver.swift:117-126
    Deleting the provider-specific resolver path means a probe that only yields an unrecognized compact fallback extra window has no primary or secondary lane to select. Automatic then returns no metric despite usable parsed quota data; include that fallback before returning nil.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.94

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f8636cb37eb0.

Label changes

Label justifications:

  • P2: The PR changes user-visible quota selection and persisted layout behavior, with normal-priority compatibility regressions that must be resolved before merge.
  • merge-risk: 🚨 compatibility: The branch can alter existing Antigravity display semantics and regress legacy Pace and highest-usage behavior during upgrade.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides make test and make check transcript, but no redacted after-fix run demonstrates exhausted-window selection, Antigravity menu-bar output, or the Pace % layout in a freshly built app; add runtime proof and update the body for automatic re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • PR-head scope: The reviewed head eed654fe585b41f1648b202273b9aa1edfaaa44c changes 40 files (324 additions, 998 deletions), including resolver, highest-usage, Antigravity probe, stored-layout, renderer, and test surfaces. (Sources/CodexBar/MenuBarMetricWindowResolver.swift:117, eed654fe585b)
  • Highest-usage regression remains: The exhausted-window resolver can select a 100%-used lane while the highest-usage exclusion path still removes non-special providers whose selected metric is exhausted unless all lanes are exhausted, defeating the intended visibility for partially exhausted providers. (Sources/CodexBar/MenuBarMetricWindowResolver.swift:140, eed654fe585b)
  • Legacy Pace compatibility remains incomplete: Legacy Pace layouts are migrated to the new pacePercent token, but the runtime data supplies that token only when weekly pace exists; the established percent fallback is not preserved for providers without pace metadata. (Sources/CodexBar/MenuBarLayout.swift:221, eed654fe585b)
  • Antigravity contract changed without complete surface migration: The probe now maps Gemini five-hour and Gemini weekly quotas into primary/secondary while existing provider labels and fallback behavior were built around Gemini versus Claude/GPT families; the PR discussion explicitly describes this as a simplifying product choice rather than a narrowly established bug fix. (Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift:208, eed654fe585b)
  • Repository policy applied: The repository policy requires focused stable tests and freshly built bundle-level validation for UI/runtime behavior; the PR supplies test and lint transcript only, not a redacted after-fix menu-bar run. (AGENTS.md, f8636cb37eb0)

Likely related people:

  • steipete: The repository and current main branch are owned under this account; the remaining blocker is the intended Antigravity user-facing contract rather than a mechanical contribution detail. (role: repository owner and likely product decision owner; confidence: low; commits: f8636cb37eb0; files: Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift, Sources/CodexBar/MenuBarMetricWindowResolver.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (5 earlier review cycles)
  • reviewed 2026-07-20T03:50:04.281Z sha 39bcea8 :: needs real behavior proof before merge. :: [P1] Keep partially exhausted providers eligible for highest usage | [P2] Preserve stringsdict plural formatting
  • reviewed 2026-07-20T05:32:56.538Z sha 289349a :: needs real behavior proof before merge. :: [P2] Keep default providers on supported automatic lanes | [P2] Preserve stringsdict plural formatting
  • reviewed 2026-07-20T10:56:27.252Z sha eed654f :: needs real behavior proof before merge. :: [P2] Preserve the percent fallback for migrated Pace layouts | [P2] Refresh custom Pace % layouts when pace changes | [P1] Resolve the Gemini-only Antigravity display contract
  • reviewed 2026-07-20T11:38:20.115Z sha eed654f :: needs real behavior proof before merge. :: [P1] Keep partially exhausted providers eligible for highest usage | [P2] Restore plural-aware localized formatting | [P2] Preserve the legacy Pace percent fallback | [P2] Include Pace % in the icon refresh signature | [P2] Align Antigravity secondary labels with the new lane | [P2] Retain the Antigravity compact fallback in Automatic
  • reviewed 2026-07-20T12:26:21.581Z sha eed654f :: needs real behavior proof before merge. :: [P1] Keep partially exhausted providers eligible for highest usage | [P2] Preserve the quota-percent fallback for migrated Pace layouts | [P2] Refresh custom Pace % layouts when pace changes | [P2] Align Antigravity lane labels with Gemini-only mapping | [P2] Keep the compact Antigravity fallback selectable in Automatic

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 289349ab10

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +175 to +177
let windows = [snapshot.primary, snapshot.secondary, snapshot.tertiary].compactMap(\.self)
if let exhausted = windows.filter({ $0.usedPercent >= 100 }).max(by: { $0.usedPercent < $1.usedPercent }) {
return exhausted

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep default providers on supported automatic lanes

For default providers with independent lanes, such as Gemini's Pro/Flash/Flash Lite quotas, this exhausted-first branch now lets an exhausted lower-priority tertiary lane win automatic selection even though Gemini's automatic behavior is expected to stay on the primary lane (see StatusItemAnimationTests.swift:578-612, which only covers the 95% case). In merged-icon/highest-usage mode that chosen 100% metric then falls through to UsageStore+HighestUsage.swift:126 and excludes the provider entirely, so a user with Pro still usable but Flash Lite exhausted loses Gemini from the unified icon instead of seeing the usable primary quota; limit this default exhausted-first behavior to providers whose partial exhaustion is handled, or add matching all-lanes-exhausted exclusion logic.

Useful? React with 👍 / 👎.

When no quota is exhausted, the automatic metric now prefers
5-hour session windows (windowMinutes=300) over weekly windows
for the Antigravity provider. The session limit is the immediate
constraint users care about; showing a weekly reset countdown
(e.g. 'in 6d 18h') is less actionable than the session window.
@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/exhausted-quota-display-priority branch from 7d2a263 to 5939580 Compare July 20, 2026 08:46
@Yuxin-Qiao Yuxin-Qiao changed the title Fix automatic quota display priority for exhausted windows Fix automatic quota display priority for exhausted windows & Antigravity session preference Jul 20, 2026
@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5939580582

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +196 to +198
let sessionWindows = usableWindows.filter {
$0.windowMinutes == Self.antigravitySessionCadence
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Antigravity ranking and rendering aligned

When Antigravity has a usable 5-hour quota at 0% and a usable weekly quota at 99% with the default antigravityPrioritizeExhaustedQuotas == false, this new session-window preference makes the rendered automatic metric choose the 5-hour window. However UsageStore.menuBarMetricWindowForHighestUsage still calls its own unchanged Antigravity helper in Sources/CodexBar/UsageStore+HighestUsage.swift:41-139, which ranks the highest-used usable quota, so highest-usage mode can select Antigravity based on 99% weekly usage while the status item renders 0% 5-hour usage. Keep the ranking and rendering paths on the same resolver/rule so unified selection does not display a different quota than the one it selected.

Useful? React with 👍 / 👎.

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a56c65ca6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

]])
case .pace:
return MenuBarLayout(lines: [[icon, .runsOut]])
return MenuBarLayout(lines: [[icon, .pacePercent]])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve pace fallback in migrated layouts

When a provider cannot compute weeklyPace (missing weekly/reset metadata; the legacy .pace path explicitly falls back to the selected percent in MenuBarDisplayText.displayText), this migrated layout now renders only .pacePercent, whose renderer shows when data.pacePercent is nil. If a legacy Pace user opens the layout editor or changes size/gap, that migration is persisted and the menu bar regresses from icon + quota percent to icon + placeholder for providers without pace data; keep the percent fallback when translating legacy .pace into a stored layout.

Useful? React with 👍 / 👎.

Comment on lines +64 to +65
let pacePercent = pace
.flatMap { MenuBarDisplayText.paceText(pace: $0) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track Pace % in the stored-layout icon signature

This new stored-layout value depends on weeklyPace, but storeIconObservationSignature() only signs the legacy menuBarDisplayText and cost tokens. For a user with a custom layout containing Pace % while the legacy display mode remains Percent, historicalPaceRevision changes wake the icon observer but the signature is unchanged, so updateIcons is skipped and the menu bar keeps showing the old pace value until some unrelated signed field changes; add a layout pace signature like the existing cost signature path.

Useful? React with 👍 / 👎.

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper Simplified Antigravity logic: the menu bar now only tracks Gemini's quota (primary = 5h, secondary = weekly). Claude/GPT limits are kept parsed under extraRateWindows so they still render in the dropdown menu card. Removed over 1,100 lines of complex cross-family merging code. Ready for review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eed654fe58

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

matching: { $0.lowercased().contains("claude") || $0.lowercased().contains("gpt") },
in: namedWindows)
matching: { name in
name.lowercased().contains("gemini")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore Claude/GPT quota selection for Antigravity

When the quota-summary payload contains both Gemini and Claude/GPT weekly buckets, this secondary representative now filters for Gemini again, even though Antigravity's metadata still labels the secondary lane as Claude and GPT (AntigravityProviderDescriptor.swift:12-13). That makes the menu/status surfaces show Gemini weekly usage under the Claude/GPT label and completely ignore a more constrained Claude/GPT quota; keep this predicate on the Claude/GPT family unless the rest of the UI is migrated to session/weekly semantics too.

Useful? React with 👍 / 👎.

}
return windows.max(by: { $0.usedPercent < $1.usedPercent })
// 2. Otherwise, fall back to the default order
return snapshot.primary ?? snapshot.secondary

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve Antigravity compact fallback in Automatic

For Antigravity local probes with only an unrecognized selectable text model, AntigravityStatusProbe still creates an antigravity-compact-fallback-* extra window, but after deleting the provider-specific branch this default fallback only returns snapshot.primary ?? snapshot.secondary. In that scenario both are nil, so Automatic produces no metric and the provider disappears from menu-bar/Overview ranking despite having usable quota data; include the compact fallback extra window before returning nil.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 20, 2026
@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. and removed P1 Urgent regression or broken agent/channel workflow affecting real users now. labels Jul 20, 2026
…eep partially exhausted Antigravity eligible for highest-usage

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec48432cfc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// Default path:
// 1. Prioritize any exhausted window (usedPercent >= 100)
let windows = [snapshot.primary, snapshot.secondary, snapshot.tertiary].compactMap(\.self)
if let exhausted = windows.filter({ $0.usedPercent >= 100 }).max(by: { $0.usedPercent < $1.usedPercent }) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Respect the Antigravity exhausted-quota opt-out

When Antigravity is in Automatic mode with the default antigravityPrioritizeExhaustedQuotas == false, this default branch is still reached and returns any 100% lane before the normal session/primary preference; the setting is no longer consulted. In accounts with one exhausted Antigravity lane and another still usable, the “Prioritize exhausted quotas” toggle now behaves as if it is always enabled for the menu bar and highest-usage ranking, so gate this exhausted-first return for Antigravity on the setting or restore the provider-specific non-exhausted selection.

Useful? React with 👍 / 👎.

Comment on lines +60 to +64
let pace = paceWindow
.flatMap { self.store.weeklyPace(provider: provider, window: $0, now: now) }
let runsOut = pace
.flatMap { UsagePaceText.weeklyDetail(provider: provider, pace: $0, now: now).rightLabel }
let pacePercent = pace

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compute Pace % from the selected legacy lane

For stored layouts migrated from legacy Both/Pace with an explicit lane selection, this new Pace % value uses the shared pace computed from windows.weekly ?? windows.automatic, but legacy menuBarPaceWindow used the selected percent window for non-combined providers/modes. For example, Claude with Primary selected can keep showing the session percent while this token shows weekly pace instead of the selected session pace after the user opens/saves the layout editor; make the token carry the intended window or reuse the legacy pace-window resolver during migration/rendering.

Useful? React with 👍 / 👎.

…to satisfy length limits, and fix formatting
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown

ClawSweeper status: review started.

I am starting a fresh review of this pull request: Fix automatic quota display priority for exhausted windows & Antigravity session preference This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d64334f000

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 157 to +158
let primary = primaryQuota.map(Self.rateWindow(for:))
let secondary = secondaryQuota.map(Self.rateWindow(for:))
let secondary: RateWindow? = nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Let Claude/GPT coexist with Antigravity fallback

When a local Antigravity payload has no recognized Gemini quota but does include an unrecognized selectable text model plus any Claude/GPT quota, secondaryQuota is non-nil so the fallback guard above never sets compactFallbackModelID; this line then drops the Claude/GPT lane anyway. Since Claude/GPT is no longer rendered as a menu-bar lane, its presence suppresses the only compact fallback for new/unclassified local Gemini-style quotas, leaving automatic display with no usable primary/secondary metric.

Useful? React with 👍 / 👎.

Comment on lines 228 to +230
.percent(window: Self.percentWindow(for: metricPreference, provider: provider)),
.separatorDot,
.runsOut,
.pacePercent,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid duplicating percent in migrated Both layouts

For legacy Both users whose provider cannot compute pace, persisting this migrated layout (for example via the layout editor or size/gap controls) renders the percent token and then .pacePercent, whose renderer falls back to the automatic percent when pace is nil. That changes the legacy fallback from a single quota like 42% to 42% · 42%; keep the pace fallback out of the sibling token or omit the separator/pace token when no pace is available.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant