Skip to content

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

Merged
steipete merged 1 commit into
steipete:mainfrom
Yuxin-Qiao:fix/exhausted-quota-display-priority
Jul 29, 2026
Merged

Fix automatic quota display priority for exhausted windows & Antigravity session preference#2352
steipete merged 1 commit 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 thread Sources/CodexBar/UsagePaceText.swift Outdated
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 21, 2026, 6:03 AM ET / 10:03 UTC.

Summary
The branch prioritizes exhausted automatic quota windows and simplifies Antigravity’s menu-bar primary lanes to Gemini session and weekly quotas while retaining other model quotas as card extras.

Reviewed head: aae6f716f47aaee8198652898234e068531d5266

Reproducibility: yes. from source: configure Antigravity Automatic mode with antigravityPrioritizeExhaustedQuotas disabled and provide a usable Gemini lane plus an exhausted Gemini lane; the new generic resolver selects the exhausted lane because the preference-aware branch was removed. A real app run is still needed to prove the visible menu-bar result.

Review metrics: 2 noteworthy metrics.

  • Patch surface: 20 files affected; 626 additions, 1,398 deletions. The PR combines a general resolver correction with a broad Antigravity display-contract simplification, increasing the need for upgrade and runtime proof.
  • Runtime proof: 0 after-fix runtime artifacts. The body contains test and lint transcripts only, which do not demonstrate the native menu-bar result.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🦐 gold shrimp
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:

  • [P1] Resolve the Antigravity preference contract and add regression tests for both preference states.
  • Make cadence-unknown model-quota labels neutral or derived from parsed window cadence.
  • Update the PR body with redacted runtime proof from a freshly built app; if automatic re-review does not trigger, ask a maintainer to comment @clawsweeper re-review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The body shows test and lint output but no redacted after-fix run of the rebuilt menu-bar app; add a screenshot, recording, or terminal/live output proving exhausted-window selection and Antigravity lane display, with private account data redacted. 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 Antigravity users with the exhausted-quota preference disabled can have an exhausted Gemini lane displayed anyway, changing stored-setting behavior without migration or explicit retirement.
  • [P1] Model-quota snapshots without a known cadence can be shown as “Gemini 5-hour”, which misstates what the provider returned.
  • [P1] Tests and lint output do not prove the changed native menu-bar behavior in a real rebuilt app.

Maintainer options:

  1. Restore preference-aware selection (recommended)
    Retain the Gemini-only lane mapping but make exhausted-first selection conditional on the existing Antigravity preference, then add both-setting regression tests.
  2. Approve an intentional contract retirement
    If unconditional exhausted-first behavior is desired, explicitly retire or migrate the persisted preference and document the upgrade behavior before merge.
  3. Pause the Antigravity simplification
    Keep the generic exhausted-window correction separate and defer the Antigravity contract change until its user-setting behavior is decided.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Restore preference-aware Antigravity automatic selection and add focused tests for enabled and disabled exhausted-quota preference states.

Next step before merge

  • [P1] A maintainer must decide whether the persisted Antigravity preference remains supported; runtime proof must also come from the contributor’s real setup.

Maintainer decision needed

  • Question: Should Antigravity Automatic mode continue honoring the existing “Prioritize exhausted quotas” preference after moving its primary lanes to Gemini session and weekly quotas?
  • Rationale: The patch deliberately replaces a persisted user preference with unconditional exhausted-first behavior; source review can identify the compatibility break but cannot choose whether retiring that behavior is intended product direction.
  • Likely owner: steipete — Repository-level product direction is required to decide whether this existing preference remains part of the Antigravity contract.
  • Options:
    • Preserve the existing preference (recommended): Keep Gemini-only lane mapping, but gate exhausted-first Antigravity selection on the stored preference and retain regression coverage for both settings.
    • Retire the preference deliberately: Remove or migrate the setting with visible upgrade documentation and tests that establish unconditional exhausted-first behavior as the supported contract.

Security
Cleared: The reviewed patch changes Swift display, parsing, and tests only; no dependency, workflow, secret, permission, download, or supply-chain change is present.

Review findings

  • [P1] Preserve the Antigravity exhausted-quota preference — Sources/CodexBar/MenuBarMetricWindowResolver.swift:117
  • [P2] Keep model-quota Antigravity labels cadence-neutral — Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift:12-13
Review details

Best possible solution:

Keep the existing Antigravity preference effective unless a maintainer explicitly retires it with an upgrade path, derive labels from actual parsed cadence, and add focused regression coverage plus redacted after-fix runtime proof for exhausted-window selection and Antigravity display.

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

Yes, from source: configure Antigravity Automatic mode with antigravityPrioritizeExhaustedQuotas disabled and provide a usable Gemini lane plus an exhausted Gemini lane; the new generic resolver selects the exhausted lane because the preference-aware branch was removed. A real app run is still needed to prove the visible menu-bar result.

Is this the best way to solve the issue?

No, not yet. The generic exhausted-window correction can remain, but silently making an existing Antigravity preference ineffective is not the narrowest compatible solution, and cadence-unknown quotas need neutral labeling.

Full review comments:

  • [P1] Preserve the Antigravity exhausted-quota preference — Sources/CodexBar/MenuBarMetricWindowResolver.swift:117
    The removed provider-specific branch was the only path that honored antigravityPrioritizeExhaustedQuotas. Automatic mode now reaches generic exhausted-first selection regardless of that stored setting, so users who disabled the option can see an exhausted Gemini lane while another Gemini lane remains usable. Keep the setting effective or explicitly retire it with migration and upgrade coverage.
    Confidence: 0.95
  • [P2] Keep model-quota Antigravity labels cadence-neutral — Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift:12-13
    The new “Gemini 5-hour” metadata label also renders model-quota snapshots whose primary RateWindow has no parsed cadence. That tells users a five-hour limit was observed when the source only provided a model-level quota; derive the label from windowMinutes or keep a neutral model-quota label.
    Confidence: 0.93

Overall correctness: patch is incorrect
Overall confidence: 0.92

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P1: The patch can silently override an existing persisted Antigravity preference for current users.
  • merge-risk: 🚨 compatibility: Unconditional exhausted-first selection changes the behavior of existing Antigravity configurations that opted out of that policy.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The body shows test and lint output but no redacted after-fix run of the rebuilt menu-bar app; add a screenshot, recording, or terminal/live output proving exhausted-window selection and Antigravity lane display, with private account data redacted. 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:

  • Antigravity preference bypass: The latest PR patch removes the Antigravity-specific automatic-resolution branch that consulted antigravityPrioritizeExhaustedQuotas, leaving the new generic exhausted-first resolution to select a 100% Gemini lane even when the stored preference is disabled. (Sources/CodexBar/MenuBarMetricWindowResolver.swift:117, aae6f716f47a)
  • Cadence-specific labels: The PR changes Antigravity metadata labels to “Gemini 5-hour” and “Gemini weekly”, while its own review discussion identifies that the modelQuotas path can construct a primary window with no parsed windowMinutes; that makes the five-hour label inaccurate for that source. (Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift:12, aae6f716f47a)
  • Prior review continuity: The supplied review history already raised the exhausted-quota preference regression; later commits address other follow-up areas but the final pull-file diff still removes the preference-aware resolver branch. (Sources/CodexBar/MenuBarMetricWindowResolver.swift:117, aae6f716f47a)
  • Proof supplied: The PR body provides make test and make check transcripts, but no after-fix menu-bar or terminal runtime evidence demonstrates the exhausted-window selection or the Antigravity mapping in a freshly built app. (aae6f716f47a)

Likely related people:

  • steipete: This change alters the established Antigravity quota-display contract and a persisted preference, so repository-level direction is needed; the supplied review data does not provide reliable current-main line attribution for another feature owner. (role: repository owner and likely product decision owner; confidence: low; files: Sources/CodexBar/MenuBarMetricWindowResolver.swift, Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.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 (6 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
  • reviewed 2026-07-20T13:29:48.318Z sha eed654f :: needs real behavior proof before merge. :: [P1] Keep partially exhausted providers eligible for highest usage | [P2] Preserve the legacy Pace percent fallback | [P2] Refresh custom Pace % layouts when pace changes | [P2] Align Antigravity labels with the new Gemini lanes | [P2] Retain Antigravity compact fallback 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 👍 / 👎.

@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".

Comment thread Sources/CodexBar/MenuBarLayout.swift Outdated
]])
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. P2 Normal priority bug or improvement with limited blast radius. 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. P1 Urgent regression or broken agent/channel workflow affecting real users now. 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: 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 👍 / 👎.

@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 thread Sources/CodexBar/MenuBarLayout.swift Outdated
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 👍 / 👎.

@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/exhausted-quota-display-priority branch from 0248f83 to f1341f1 Compare July 21, 2026 09:35

@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: 0248f836b7

ℹ️ 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".

displayName: "Antigravity",
sessionLabel: "Gemini Models",
weeklyLabel: "Claude and GPT",
sessionLabel: "Gemini 5-hour",

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 model-quota Antigravity labels cadence-neutral

When Antigravity uses the remote/local modelQuotas path rather than quotaSummary, the primary window is built from a representative Gemini model with windowMinutes: nil in rateWindow(for:), but menu/card/widget fallback rendering titles that primary row from this metadata. This new label therefore shows a model-level Gemini quota as “Gemini 5-hour” even though no 5-hour cadence was parsed; keep a neutral label for non-quota-summary snapshots or derive the label from the window cadence.

Useful? React with 👍 / 👎.

@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/exhausted-quota-display-priority branch from f1341f1 to 94e168c Compare July 21, 2026 10:00
@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. 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. labels Jul 23, 2026
Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
@steipete
steipete force-pushed the fix/exhausted-quota-display-priority branch from aaa268c to da343ce Compare July 29, 2026 01:50
@steipete
steipete merged commit a0ceafb into steipete:main Jul 29, 2026
9 checks passed
@steipete

Copy link
Copy Markdown
Owner

Merged after maintainer repair and exact-head verification.

The final review found the generic exhausted-window priority fix sound once the change was reduced to the resolver and highest-usage ownership boundary. The existing default-off Antigravity “Prioritize exhausted quotas” preference remains effective for both disabled and enabled states, and cadence-unknown Antigravity model data keeps its neutral label.

Verification on final head da343ce5308ea206e3597d296e80852102546780:

  • Hosted CI: https://github.com/steipete/CodexBar/actions/runs/30415205858 — all Linux builds, both macOS test shards, lint, aggregate checks, and security checks passed.
  • Focused local suites: MenuBarMetricWindowResolverTests (37), UsageStoreHighestUsageTests (23), and AntigravityStatusProbeTests (60).
  • Final AutoReview: clean, with no accepted or actionable findings.

Thank you, @Yuxin-Qiao, for identifying the exhausted-window problem and contributing the original implementation and tests.

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. P1 Urgent regression or broken agent/channel workflow affecting real users now. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants