Skip to content

feat(menubar): say whether a quota window lasts until its reset - #1287

Open
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:feat/1215-reset-verdict
Open

feat(menubar): say whether a quota window lasts until its reset#1287
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:feat/1215-reset-verdict

Conversation

@ozymandiashh

Copy link
Copy Markdown
Collaborator

Summary

  • The Capacity Dock's window columns and the agent-tab quota hover card now answer "am I going to make it?", not just "when does this reset?": one line under the bar reading Lasts until reset, Runs out in 2d 8h, or Won't last until reset on windows of 6 hours or less, where a linear run-out ETA is not defensible.
  • It is the same projection the Plan tab's deficit/reserve caption has used since menubar: quota windows show no pace — add run-out projection (deficit, lasts-to-reset / runs-out-in) #726/menubar: linear pace on Codex quota windows — deficit/reserve, projection, run-out ETA #728QuotaPace.evaluate stays the only pace math in the app, and this is a (text, willOverflow) reduction of its result — so the three surfaces cannot disagree. All of menubar: quota windows show no pace — add run-out projection (deficit, lasts-to-reset / runs-out-in) #726's guards come along: silent in the first 3% of a window, on an exhausted window, without a reset time, and on clock skew, with the <= 6h ETA suppression kept rather than crying wolf over one burst.
  • QuotaSummary.Window carries no window length, so rather than thread one through ~15 adapter call sites, QuotaPace.inferredWindowSeconds(label:resetsAt:) reads it from the normalized label the adapters already derive from the exact API duration (Weekly, 5-hour, Weekly · Opus, Monthly usage limit). Calendar months are measured back from the reset date in UTC, mirroring how the Codex spend window is derived. A label that implies no length (Copilot's Premium requests, Cursor's Team pool) keeps the row silent instead of guessing.
  • The dock reserves the line's height whether or not a column has a verdict, because the glance panel's frame is computed rather than fitted — the same reason the staleness notice has its own reserved height — so a projection crossing in or out of silence cannot resize the bubble under the pointer. The hover card is fitted, so there the line collapses.

Closes #1215

Testing

  • I have tested this locally against real data (not just unit tests)
  • npm test passes — not applicable, no TypeScript touched; cd mac && swift build succeeds (Build complete, 53.76s)
  • npm run build succeeds — not applicable; macOS target only

mac/Tests/CodeBurnMenubarTests/QuotaPaceVerdictTests.swift adds 12 XCTest cases over the pure
(utilization, elapsed fraction, window length) -> String? mapping: all four outcomes
(lasts / runs out with an ETA / won't last on a 5h and on an exactly-6h window / silent), the
early-window silence at 2% and 1% elapsed with 5% speaking, exhausted, missing reset and clock
skew, the countdown wording, the percent 0...1 conversion, and label inference including
Weekly · Opus, GPT-5.3-Codex-Spark · 5-hour, Gemini Models · Five-hour,
Monthly usage limit against a February-in-UTC reset, and the bucket labels that must stay
silent. CapacityDockGlanceTests is updated for the three hard-coded panel heights the
reserved line moves.

Note: my machine has a CLT-only Swift toolchain with no swift-testing module, so the test
target does not compile locally (error: no such module 'Testing' from an existing test file)
and I could not run swift test. To avoid shipping unverified assertions I executed every
expectation in the new file against the real QuotaPace.swift through a standalone swiftc
harness — 43/43 pass — but CI's swift test is the real check here.

The Plan tab has answered "am I going to make it?" since getagentseal#726/getagentseal#728, but
the two surfaces people actually glance at — the Capacity Dock's window
columns and the agent-tab quota hover card — still only said when the
window resets, which is the one fact that does not answer the question.

Both now draw one line under the bar, off the same projection:
`Lasts until reset` while the linear projection lands at or under 100% at
reset, `Runs out in 2d 8h` when it overflows on a window long enough for
a whole-window rate to be defensible, and `Won't last until reset` when
it overflows on a window of 6 hours or less, which keeps getagentseal#726's ETA
suppression rather than crying wolf over one burst. It stays silent in
the first 3% of a window, on an exhausted window, without a reset time,
and on clock skew — the same guards `QuotaPace.evaluate` already has,
which stays the only pace math in the app.

`QuotaSummary.Window` carries no window length, so rather than thread
one through ~15 adapter call sites the length is inferred from the
normalized label the adapters already derive from the exact API duration
("Weekly", "5-hour", "Weekly · Opus", "Monthly usage limit"). Calendar
months are measured back from the reset date in UTC, mirroring how the
Codex spend window is derived; a label that implies no length keeps the
row silent rather than guessing one.

The dock reserves the line's height whether or not a column has a
verdict, because the glance panel's frame is computed rather than
fitted: a projection crossing in or out of silence must not resize the
bubble under the pointer. The hover card is fitted, so there the line
collapses.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

menubar: bring the lasts-until-reset verdict to the Capacity Dock and quota hover card

1 participant