feat(omarchy): show session quota, weekly quota and weekly pace in the bar - #3794
jsonMartin wants to merge 5 commits into
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. Reviewed September 21, 2026, 3:17 PM ET / 19:17 UTC (Revision 5). ClawSweeper reviewWhat this changesAdds session and weekly quotas, weekly pace, provider-count controls, and optional per-model caps to the Omarchy bar, alongside quota-pool deduplication and polling cleanup. Merge readiness⛔ Blocked before merge - 3 items remain Keep open: the feature remains distinct from current main and has convincing installed-bar proof. No blocking code defect was found; the previously identified product decision remains unresolved. Priority: P2 Review scores
Verification
How this fits togetherCodexBar’s Linux backend converts CLI usage results and saved display preferences into a private desktop snapshot. The Omarchy widget polls that snapshot to display quota information without running provider queries itself. flowchart LR
A[CLI usage and pace] --> C[Shared quota model]
B[Saved display preferences] --> D[Linux desktop backend]
C --> D
D --> E[Private desktop snapshot]
E --> F[Omarchy bar and popup]
D --> G[Native tray and notifications]
Decision needed
Why: The contributor explicitly leaves this choice open, and successful rendering on one desktop cannot establish an acceptable default for existing bar layouts. Before merge
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Keep the shared backend formatting and preserve compact labels on upgrade unless maintainers explicitly approve the wider default. Do we have a high-confidence way to reproduce the issue? Not applicable to the central feature request; main and v0.64.0 source establish the compact-only bar behavior, and supplied installed-bar proof demonstrates the proposed display. Is this the best way to solve the issue? Yes, formatting in the shared backend and reusing CLI pace values is a coherent approach; the appropriate upgrade default still requires a product choice. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 1caaeb8837dd. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (4 earlier review cycles)
|
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.
f9d9e98 to
4bb8cc5
Compare
…e bar The bar showed one quota per provider and no pace, so the weekly burn rate was only visible by opening a window. Show each provider's session quota, weekly quota and weekly pace. Nothing here recomputes pace. The CLI already emits a signed delta per window, produced by Core, so the shared model carries it through and renders it in the compact form of MenuBarDisplayText.paceText. The pace shown is the weekly window's, never whichever lane is most constrained, and a pace Core cannot compute contributes no segment rather than a placeholder that reads like data. Lanes are resolved from the cadence a provider reports, the way Core's semantic windows do, so no provider name is hard-coded and a provider without a session window emits neither that segment nor its separator. Three rules came out of testing against real provider shapes rather than from design: - Antigravity marks a per-family summary set with quota-summary ids, and its positional window is only whichever family represents them, so a tighter family was hidden behind it. Matching on that marker rather than on percentages matters: Claude's general weekly can coincide with one of its per-model caps, and reading that coincidence as a summary replaced the general quota with a cap scoped beneath it. - Kimi delivers a subscription-only account's entire quota through extraRateWindows, so treating every extra as an optional sub-cap dropped it. - Cursor bills its total, its Auto/Composer usage and its API usage over one cycle, so keeping only the tightest of a duration replaced the headline quota with a subquota. Percentages run through the existing quota preference, so the bar follows the used or remaining setting without the adapter inverting anything, and the existing Show pace preference now governs the bar as well as the native cards. Caps scoped to a single model are off by default behind a new preference, since most providers that publish them restate a general lane. A new Providers in the bar preference bounds how many providers the bar shows, two by default, and counts the rest, so an upgrade cannot widen an existing multi-provider bar. It is display only: every configured provider is still polled and listed in the popup. At the default font each character occupies roughly 7 logical pixels, so four providers each showing a session lane, a weekly lane and a pace come to about 1500 logical pixels; the README says so, and 0 shows every provider where the display has room. The tray tooltip names the provider's own leading quota. A cadence the bar derives from a per-model cap is skipped while the provider reports a quota of its own, so Cursor's exhausted weekly Grok allowance cannot read as an exhausted account in a tooltip that carries no lane name. The adapter also stopped reusing a previous poll's body, which let a backend that had gone away keep reporting the quota it last had.
4bb8cc5 to
498aaac
Compare
…up-duplicates # Conflicts: # Integrations/Linux/Shared/Usage.js # Integrations/Linux/tests/test_desktop.py
# Conflicts: # Integrations/Linux/Shared/Usage.js
TL;DR
The Omarchy bar now shows each provider's session limit, weekly limit and weekly pace, instead of one usage percentage. You can see your weekly usage and pace without opening a window. The bar follows your existing display settings and shows two providers by default. Each provider's text is longer than before, so the bar gets wider; see the question for the maintainer below. This builds on #3799.
What changes
+N. Hidden providers are still polled, listed in the popup, and notified about.For example, the bar can show:
The first value is the 5-hour limit, and the next is the weekly limit. The last is weekly pace: how far usage is above or below Core's expected usage.
This synthetic snapshot compares Codex with weekly pace, Claude with an exhausted per-model weekly cap, Antigravity with its separate usage pools, and z.ai:
mainsummary(tray tooltip)CX 37% · CL 78% +2CX 37% · CL 78% +2CX 37% · CL 78% +2barLabel(Omarchy bar)CX 5H 37% · 7D 61% · +14% · CL 5H 78% · 7D 11% +2CX 5H 37% · 7D 61% · +14% · CL 5H 78% · 7D 11% · antigravity 5H 97% · 7D 93% · zai 5H 88% · 7D 70%Question for the maintainer
The provider count stays at two after an upgrade, but each provider's text gets longer. Before:
CX 37% · CL 78% +2. After:CX 5H 37% · 7D 61% · +14% · CL 5H 78% · 7D 11% +2. Is the wider default acceptable, or should upgrades keep the short one-percentage text until the user opts in? Either is a small change.Details
Pace and display settings
The CLI already reports Core's signed pace value for each usage period. The shared model passes it through in the compact format used by
MenuBarDisplayText.paceText; this PR does not recalculate it. The bar uses the weekly value only. If Core cannot calculate weekly pace, the bar leaves it out instead of showing a placeholder.Limits are identified by their reported duration, as they are in Core, without hard-coded provider names. If a provider has no session limit, the bar omits that value and its separator. Percentages use the existing used-or-remaining preference; the widget does not invert them. Show pace controls both the bar and the native cards.
Per-model caps are off by default because most providers that report them repeat a general limit. They can be enabled with Show per-model caps in the bar.
Choosing which limits to show
These rules came from checking real provider output:
antigravity-quota-summary-*ids, and copies each family's most constrained pool intoprimaryorsecondary(AntigravityStatusProbe.swift:201). For each duration the bar uses the pool with the least allowance left, so an exhausted family cannot hide behind an unused one.antigravity-compact-fallback-*window when neither family has a pool to show. That marked window stands in for the provider's quota. Other per-model extras without a duration do not.CursorStatusProbe.swift:460). Sharing a duration does not make them the same limit, so the total stays the main quota even when a sub-limit has less left.extraRateWindows. The bar shows it instead of treating it as an optional per-model cap.The tray tooltip uses the provider's own leading quota. If the provider reports its own quota, the tooltip skips a duration inferred from a per-model cap. For example, Cursor's monthly Total at 75% with an exhausted weekly Grok allowance reads
cursor 75%, notcursor 0%.Width and upgrades
Providers in the bar is under Settings → display. It defaults to two, the number shown before this PR, and counts the rest as
+N. It only affects display: hidden providers are still polled, listed in the popup, and notified about.0(All) shows every provider where the display has room; four providers with session, weekly and pace take about 1500 logical pixels.Depends on
This builds on #3799, which sits on
mainnow that #3785 has merged (as9d3f6bf54). GitHub's native stacked pull requests do not support cross-fork stacks, so this branch also carries #3799's commits. This PR's own change is commit498aaac03. The branch hasmainmerged in (at1caaeb883) so it merges cleanly; once #3799 merges, the diff reduces to this PR's change.This was rebuilt on the merged #3785. Extra keys are now
extra:<id>. Fractional duration labels in the popup, notification identities and IPC key hashing from9d3f6bf54are unchanged. All tests added by #3785 onmainare kept.Proof
All data is synthetic. Each scenario runs the real
codexbar-linuxwith--background --no-trayagainst a fake CLI, in an isolated HOME, and readscodexbar-linux --snapshot.Installed Omarchy bar. This commit's
Panel.qmlwas installed withinstall.py --omarchyon the Omarchy shell running on Hyprland. The synthetic backend served the real runtime socket, which the installed widget polls. The screenshot shows two providers and+2for the other two, using the default display limit:The snapshot table above shows that pace follows the weekly limit only. Claude's exhausted per-model cap stays out of the bar while Show per-model caps in the bar is off.
Upgrade.
test_settings_from_before_the_bar_preferences_survive_an_upgradestarts the real binary with alinux.jsonwritten before these preferences existed. It sets custom order[claude, codex], quota shown as used, pace off, and refresh 600 s. The bar honours those settings, showingCL 5H 40% · CX 5H 40%in used mode. After an unrelated settings change, the file still contains those values plusshowScopedCaps: falseandbarProviders: 2.Tests
CI never loads
Panel.qmlbecause Quickshell is not installed in the workflow. The widget is checked by screenshot. The label logic is tested in the JS model; the QML only displays it.Notes for the maintainer
This is the largest PR in the set, with 766 lines added and 39 removed across nine files. The usage-limit model, selection rules, backend connection and widget need to arrive together for the bar to display the new values. I could not find a smaller shippable change.
The parts that can stand alone are separate PRs: the installer fix (#3784), extra rate windows (#3785) and provider logos (#3795).