Skip to content

fix(linux): list each Antigravity quota pool once - #3799

Closed
jsonMartin wants to merge 3 commits into
steipete:mainfrom
jsonMartin:fix/antigravity-popup-duplicates
Closed

jsonMartin wants to merge 3 commits into
steipete:mainfrom
jsonMartin:fix/antigravity-popup-duplicates

Conversation

@jsonMartin

@jsonMartin jsonMartin commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

TL;DR

This removes duplicate Antigravity usage limits from the Linux popup and Omarchy panel. Each limit appears once, with its model family in the label. The tray meters still show the limit with the least remaining allowance in each family, and the tray tooltip still shows the first of them.

What changes

  • Each Antigravity limit is listed once. Since fix(linux): surface provider-scoped rate windows and drop unmeasured ones #3785, the popup showed some limits twice.
  • The limit with the least remaining allowance in each family stays first, so the tray still shows it.
  • Each limit keeps its alert history when a different limit in the same family has less allowance left.
  • Gemini and Claude/GPT keep their own labels, even when their values are equal.
  • The popup's 8-row cap on extra limits can no longer hide the limit a family is showing.
  • Other providers are unchanged.

This synthetic example compares main with this PR. It uses four Antigravity pools, meaning separate usage allowances. Gemini weekly has 93% left and Claude/GPT 5-hour has 100% left; these are the selected limits for their families.

main this PR
summary antigravity 93% antigravity 93%
windows 7 day 93 · 5 hour 100 · Gemini 5-hour 97 · Gemini weekly 93 · Claude/GPT 5-hour 100 · Claude/GPT weekly 100 Gemini weekly 93 · Claude/GPT 5-hour 100 · Gemini 5-hour 97 · Claude/GPT weekly 100
tray meters (first two windows) Gemini weekly 93, Claude/GPT 5-hour 100 Gemini weekly 93, Claude/GPT 5-hour 100

Details

Why the rows appeared twice

Core lists each Antigravity pool as an antigravity-quota-summary-* extra window. These are the named usage limits reported by Antigravity. Core also copies the limit with the least remaining allowance in each family into the primary/secondary slots, using AntigravityStatusProbe.quotaSummaryRepresentative.

The Linux model displayed both copies. One used a duration label, such as "7 day 93%". The other used the family title, such as "Gemini weekly 93%".

rows() now keeps the selected limit in its original slot, uses its family title, and removes the extra copy. It does this before applying the 8-extra limit, so that limit cannot hide a selected pool. Each row keeps the pool's own extra:<id> key, preserving its alert history when the selected pool changes.

Matching follows Core's family selection: Gemini goes in primary, and Claude/GPT goes in secondary. Equal values therefore cannot give a pool the other family's title. This matching only runs when the named quota-summary extras described above are present.

Proof

All data below is synthetic.

Native Linux desktop. I built codexbar-linux from main (9d3f6bf54) and from this branch. Each build ran with --background --no-tray against a fake provider CLI, in an isolated HOME and XDG runtime. I read its private IPC snapshot, the data shared with the UI, using codexbar-linux --snapshot.

The snapshot carries the same usage rows the native popup and tray use, and the Omarchy panel reads it directly. The tray meters draw its first two windows, and the tray tooltip uses its summary. The table above shows that each pool appears once while each family's selected limit stays first.

Rendered card. The desktop's own Integrations/Linux/qml/UsageCard.qml was rendered offscreen by Qt 6.11. The render used qml, the software backend and grabToImage, with the snapshot rows from each branch.

main this PR

Native regression test. test_antigravity_pools_reach_snapshots_once_with_representatives_first in test_desktop.py runs this scenario through the real binary. It fails on the main build with the duplicated 7 day / 5 hour rows and passes on this branch.

Tests

  • node --test Integrations/Omarchy/test.mjs Integrations/Omarchy/notifications.test.mjs: 30 pass. The 5 new tests (3 in test.mjs, 2 in notifications.test.mjs) cover the row list, tray/summary order, a selected pool beyond the limit, alert history when the selected pool changes, and equal values across families. They fail on main.
  • CODEXBAR_LINUX_BINARY=<build of this branch> python3 -m unittest Integrations.Linux.tests.test_desktop: 16 pass, including the new Antigravity scenario, which fails against a build of main.

Refs #3785.

@clawsweeper

clawsweeper Bot commented Sep 21, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. 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. labels Sep 21, 2026
@clawsweeper

clawsweeper Bot commented Sep 21, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed September 21, 2026, 3:16 PM ET / 19:16 UTC (Revision 5).

ClawSweeper review

What this changes

The PR removes duplicate Antigravity quota rows from Linux and Omarchy while preserving family labels, tray ordering, and pool-specific notification history.

Merge readiness

Ready for maintainer review

Keep open: the duplicate rows remain on current main and in v0.64.0. This is a focused, adequately demonstrated fix with no blocking findings; the earlier representative-order concern is resolved.

Priority: P2
Reviewed head: d422616bc3658731ea499373b1f877302706c65d

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused repair with convincing native and visual evidence, useful regression coverage, and no identified blocking defect.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (screenshot): The real Linux backend’s before/after IPC snapshots exercise the changed shared row model with synthetic provider input, and inspected Qt UsageCard renders visibly show six rows reduced to four with representatives first. The latest merge preserves that algorithm and main’s label fallback.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): The real Linux backend’s before/after IPC snapshots exercise the changed shared row model with synthetic provider input, and inspected Qt UsageCard renders visibly show six rows reduced to four with representatives first. The latest merge preserves that algorithm and main’s label fallback.
Evidence reviewed 10 items Pinned introduced change: Read the complete four-file introduced diff from pinned main to the original PR head. It changes one production model and adds five Node cases plus one native snapshot case.
Current-main necessity: Main emits positional primary/secondary rows and then appends measured extras without removing representative copies. No existing Linux setting or adapter path reconciles them.
Latest release comparison: The v0.64.0 source also emits positional representatives followed by their named extras; this fix is not already present in the supplied latest release.
Findings None None.
Security None None.

How this fits together

CodexBar’s Linux desktop converts provider CLI JSON into usage rows consumed by native cards, tray indicators, notifications, and Omarchy’s private IPC adapter. Antigravity supplies both named quota pools and representative copies, which this shared model reconciles.

flowchart TD
 A[Provider CLI JSON] --> B[Shared Linux usage model]
 B --> C[Match family representatives]
 C --> D[Unique ordered quota rows]
 D --> E[Native cards and tray]
 D --> F[Quota notifications]
 D --> G[Private IPC and Omarchy]
Loading

Before merge

None.

Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production and test delta Production +22/-5 lines; tests +93/-0 lines The small production increase addresses duplicate pool rendering and is accompanied by six focused regression cases.

Root-cause cluster

Relationship: canonical
Canonical: #3799
Summary: This is the narrow quota-deduplication change; the other open branches explicitly build on it rather than replace it.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Technical review

Best possible solution:

Keep quota reconciliation in the shared Linux model so every consumer receives unique pools with stable identities and the existing representative ordering.

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

Yes: Core’s representative-plus-extras output deterministically produces duplicate rows in the current-main Linux model. Contributor native snapshots and inspected before/after renders corroborate that path; the reviewer did not execute it.

Is this the best way to solve the issue?

Yes: reconciling copies in the shared model fixes all affected consumers while retaining tray selection, privacy handling, and pool identity; no parallel implementation or new configuration is needed.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 1caaeb8837dd.

Labels

Label justifications:

  • P2: Repairs duplicate quota presentation for one provider on Linux and Omarchy without changing authentication or provider fetching.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): The real Linux backend’s before/after IPC snapshots exercise the changed shared row model with synthetic provider input, and inspected Qt UsageCard renders visibly show six rows reduced to four with representatives first. The latest merge preserves that algorithm and main’s label fallback.
  • proof: sufficient: Contributor real behavior proof is sufficient. The real Linux backend’s before/after IPC snapshots exercise the changed shared row model with synthetic provider input, and inspected Qt UsageCard renders visibly show six rows reduced to four with representatives first. The latest merge preserves that algorithm and main’s label fallback.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The real Linux backend’s before/after IPC snapshots exercise the changed shared row model with synthetic provider input, and inspected Qt UsageCard renders visibly show six rows reduced to four with representatives first. The latest merge preserves that algorithm and main’s label fallback.

Evidence

What I checked:

  • Pinned introduced change: Read the complete four-file introduced diff from pinned main to the original PR head. It changes one production model and adds five Node cases plus one native snapshot case. (Integrations/Linux/Shared/Usage.js:32, d422616bc365)
  • Current-main necessity: Main emits positional primary/secondary rows and then appends measured extras without removing representative copies. No existing Linux setting or adapter path reconciles them. (Integrations/Linux/Shared/Usage.js:32, 1caaeb8837dd)
  • Latest release comparison: The v0.64.0 source also emits positional representatives followed by their named extras; this fix is not already present in the supplied latest release. (Integrations/Linux/Shared/Usage.js:32, 3703a72b6b66)
  • Authoritative quota contract: Core selects primary from Gemini titles and secondary from Claude/GPT titles, choosing the most-used known pool while retaining every named pool in extraRateWindows. The patch matches those family predicates and compares usage, duration, and reset time. (Sources/CodexBarCore/Providers/Antigravity/AntigravityStatusProbe.swift:201, d422616bc365)
  • Consumer and privacy compatibility: Tray meters read the first two windows. Notification state is in memory and keyed by provider plus window identity; IPC continues hashing extra keys and the model continues redacting titles. No persisted settings, schema, authentication, or authority boundary changes. (Integrations/Linux/main.cpp:162, d422616bc365)
  • Review continuity: The supplied previous review had no remaining findings. GitHub comparison against its reviewed head confirms the quota reconciliation algorithm is unchanged; the merge adds main’s provider-label fallback and its native test. The original representative-order finding remains fixed. (Integrations/Linux/Shared/Usage.js:52, d422616bc365)

Likely related people:

  • jsonMartin: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Peter Steinberger: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (4 earlier review cycles)
  • reviewed 2026-09-21T04:21:14.382Z sha 06e14d8 :: needs real behavior proof before merge. :: [P2] Preserve representative quotas for compact indicators
  • reviewed 2026-09-21T04:33:21.010Z sha 23fa3f9 :: needs real behavior proof before merge. :: none
  • reviewed 2026-09-21T04:45:13.991Z sha 5098815 :: needs maintainer review before merge. :: none
  • reviewed 2026-09-21T07:18:28.189Z sha 5098815 :: needs maintainer review before merge. :: none

Antigravity reports every pool as a quota-summary extra and copies the tightest
pool of each model family into its positional windows. The popup listed both,
so each representative appeared twice: once under a bare cadence label and
again under its family title.

Show each representative in its positional slot under its family title and drop
its extra copy. The representatives stay first, so the tray meters and summary
still report the binding pools, and the extra limit can no longer hide one. The
row keeps the pool's own key, so alert history follows a pool when another
becomes binding, and families are matched as Core selects them so equal values
cannot borrow another family's title.
@jsonMartin
jsonMartin force-pushed the fix/antigravity-popup-duplicates branch from 06e14d8 to 23fa3f9 Compare September 21, 2026 04:29
@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Sep 21, 2026
@clawsweeper clawsweeper Bot added the proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. label Sep 21, 2026
…up-duplicates

# Conflicts:
#	Integrations/Linux/Shared/Usage.js
#	Integrations/Linux/tests/test_desktop.py
steipete added a commit that referenced this pull request Sep 22, 2026
Since #3785 the Linux popup and Omarchy panel rendered both the per-family representative bucket and its named copy. The shared Usage.js now keeps each representative first with its family title and bucket key and drops the duplicate, matching only on the Antigravity provider, exact quota-summary ID prefix and equal raw values. Also makes the Linux account-action log test wait for file contents rather than existence. Adopts #3799 and #3839.

Co-authored-by: jsonMartin <4033621+jsonMartin@users.noreply.github.com>
steipete added a commit that referenced this pull request Sep 22, 2026
Adopt the logo renderer and SVG packaging from #3795 independently of
#3794 and #3799. Share compact text segments with the existing summary
so quota selection, display mode, ordering, and overflow stay unchanged.
Preserve text fallback for missing logos and older IPC backends.

Closes #3795
Refs #3794

Co-authored-by: jsonMartin <4033621+jsonMartin@users.noreply.github.com>
(cherry picked from commit b6c59b6)
steipete added a commit that referenced this pull request Sep 22, 2026
Adopt the logo renderer and SVG packaging from #3795 independently of
#3794 and #3799. Share compact text segments with the existing summary
so quota selection, display mode, ordering, and overflow stay unchanged.
Preserve text fallback for missing logos and older IPC backends.

Closes #3795
Refs #3794

Co-authored-by: jsonMartin <4033621+jsonMartin@users.noreply.github.com>
(cherry picked from commit b6c59b6)
@steipete

Copy link
Copy Markdown
Owner

Thanks @jsonMartin. We reproduced the duplicate rows against current main and adopted your fix in #3844, preserving your coauthor credit. Family representatives retain their leading positions and bucket keys, preserving tray values and alert history. We additionally confined matching to Antigravity quota-summary IDs and matched Core’s title tie-breaker for identical same-family windows. All 36 portable model tests and 154 focused Swift tests pass; native desktop/Omarchy CI passed on x86_64 and ARM64, and general CI is green. Landed on main via #3844.

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

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants