Skip to content

fix(usage): Grok and Cursor usage limits show pace and the even-spend line - #21897

Merged
juliusmarminge merged 8 commits into
pingdotgg:mainfrom
wookiist:fix/grok-usage-window-duration
Nov 11, 2026
Merged

juliusmarminge merged 8 commits into
pingdotgg:mainfrom
wookiist:fix/grok-usage-window-duration

Conversation

@wookiist

@wookiist wookiist commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Fixes https://git.cafe/pingdotgg/t3code/issues/21896. The Grok and Cursor rows on Usage → Limits never show the pace icon or the even-spend marker. Their windows have no windowDurationMins, so the client cannot tell how much of the period has elapsed.

  • Grok: the billing response already reports currentPeriod.start, but grokUsageResponseToLimits does not decode it.
  • Cursor: the usage response already reports billingCycleStart, but cursorUsageResponseToLimits only reads billingCycleEnd.

Change

packages/provider-grok/src/server/usageLimits.ts now decodes currentPeriod.start and sets windowDurationMins to the rounded minutes between start and end. Because it uses the reported bounds, monthly periods get their real length instead of a fixed constant. If start is missing, not a string, unparsable, or not before end, the window stays as it is today, without a duration.

start is decoded as Schema.optional(Schema.Unknown) so an unexpected value cannot fail the whole billing read. This matches the shape https://git.cafe/pingdotgg/t3code/pulls/17061 adds to the same struct, so whichever PR lands second has a trivial rebase. https://git.cafe/pingdotgg/t3code/pulls/21802 also touches this file, and I will rebase if either lands first.

packages/provider-cursor/src/server/usageLimits.ts does the same for Cursor. It decodes billingCycleStart (a millisecond timestamp, string or number, like billingCycleEnd) and sets windowDurationMins on each monthly window to the rounded minutes between the two. If the start is missing, not positive, or not before the end, the window is reported without a duration, as before.

Scope and approval

This is a small, focused fix for an obvious bug, filed as https://git.cafe/pingdotgg/t3code/issues/21896. Claude, Codex, and OpenCode Go windows already send windowDurationMins, and the Usage page uses it the same way for every provider. Grok and Cursor already return the period start, but their adapters discard it. The fix changes one function per adapter. It does not change contracts, clients, or settings. Cursor was added after a report on https://git.cafe/pingdotgg/t3code/issues/21896.

Verification

  • Confirmed against the live billing endpoint that the Grok response includes the period start. Weekly account, period fields only: {"type":"USAGE_PERIOD_TYPE_WEEKLY","start":"2026-10-14T20:51:37.352+00:00","end":"2026-10-21T20:51:37.352+00:00"}.
  • Confirmed against the live Cursor endpoint (GetCurrentPeriodUsage) that the response includes billingCycleStart next to billingCycleEnd. For the current cycle the two differ by exactly 30 days, which is 43200 minutes.
  • Grok, before merging current main: vp test run apps/server/src/provider/GrokProvider.test.ts passed 36 tests. New cases cover a real-shaped weekly period (10080 minutes), a February monthly period (40320 minutes), unusable starts (missing, null, number, invalid string, equal to end, after end), and an HTTP decoding test that would fail if start were dropped from the schema. With the source change reverted, the two duration tests fail and the rest pass.
  • Cursor: vp test run src/server/usageLimits.test.ts in packages/provider-cursor passes 8 tests. New cases cover a 30-day and a 31-day cycle (43200 and 44640 minutes) and unusable starts (missing, empty, 0, non-numeric, equal to the end). With the source change reverted, the duration test fails and the rest pass.
  • vp fmt --check and vp lint on packages/provider-cursor/src/server: clean.
  • Manual check for Grok: ran vp run dev with an isolated --home-dir, added the Grok provider, and opened Usage → Limits with the same account.
    • Before (change reverted): the row shows only 96% left. The tooltip reads Grok: 96% left, resets in 2d 0h.
    • After: the row shows the "Under pace" icon and the even-spend marker. The tooltip reads Grok: 96% left, resets in 2d 1h, 29% of the window left.

Before:

before

After:

after

Not checked:

  • The Cursor row on the Usage page. The Cursor change is covered by the unit tests and the live response check above only.
  • A monthly Grok period on a real account (I only have a weekly one; the unit test covers it) and the mobile client.
  • After merging current main I could not install dependencies locally (pnpm install --frozen-lockfile stops on minimumReleaseAge for 29 lockfile entries), so the Grok tests, the typecheck, and the knip pre-commit step did not run locally for the final commit. CI needs to cover those.

Claude Opus 5.5 and Claude Sonnet 5.5 in T3 Code (Claude Code harness).

🤖 Generated with Claude Code

Fixes #21896

Grok's billing response reports the current period's start, but the
adapter dropped it, so the Grok window had no windowDurationMins and the
Usage page could not compute pace or place the even-spend marker.

Read currentPeriod.start and derive the window length from the reported
bounds, which also covers monthly periods of different lengths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 19, 2026
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 4160402 and 4d0eb0e.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

Grok and Cursor usage limit converters now derive windowDurationMins from reported period boundaries. Tests cover valid durations and cases where the duration is omitted because the start bound is invalid or unavailable.

Changes: Usage window duration

Layer / File(s) Summary
Derive and validate the Grok window duration
packages/provider-grok/src/server/usageLimits.ts, apps/server/src/provider/GrokProvider.test.ts
The converter calculates duration from the reported period bounds and retains its zero-usage inference conditions. Tests cover weekly and monthly periods, invalid starts, and duration calculation through readGrokAccount.
Derive and validate the Cursor window duration
packages/provider-cursor/src/server/usageLimits.ts, packages/provider-cursor/src/server/usageLimits.test.ts
The response type accepts a billing-cycle start as a string or number. The converter includes a positive duration when the bounds allow calculation. Tests cover 30- and 31-day cycles and invalid starts.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: jieyuexing, juliusmarminge

Merge Risk: Minimal · previous review 41604

No actionable issue is established for the Grok or Cursor duration changes; they are mergeable after normal checks.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly identifies the Grok and Cursor usage-limit fix and its visible effects. It is concise, specific, and related to the main changes.
Description check Passed The description includes all required sections: problem, change, scope and approval, and verification. It explains the implementation, linked issue, tests, manual checks, limitations, and remaining ve…
Linked Issues check Passed Issue #21896 requires Grok usage windows to provide the period duration so the Usage page can show the pace icon, even-spend marker, and window-percentage tooltip. grokUsageResponseToLimits now pars…
Out of Scope Changes check Passed The Grok source and tests directly implement #21896. The Cursor source and tests address the same reported symptom by using the already available billingCycleStart and are explicitly included in the…
Full details: Description check

Explanation

The description includes all required sections: problem, change, scope and approval, and verification. It explains the implementation, linked issue, tests, manual checks, limitations, and remaining verification gaps.

Full details: Linked Issues check

Explanation

Issue #21896 requires Grok usage windows to provide the period duration so the Usage page can show the pace icon, even-spend marker, and window-percentage tooltip. grokUsageResponseToLimits now parses currentPeriod.start and currentPeriod.end, computes rounded minutes, and adds windowDurationMins only for a valid positive duration. The Grok tests cover weekly periods, variable monthly periods, unusable starts, and HTTP decoding. Existing client behavior can use this field for the requested indicators.

Full details: Out of Scope Changes check

Explanation

The Grok source and tests directly implement #21896. The Cursor source and tests address the same reported symptom by using the already available billingCycleStart and are explicitly included in the current PR intent. The Cursor changes preserve the existing fallback when the start is missing, invalid, or not before the end. No unrelated contract, client, settings, or repository changes appear in the reviewed diff.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between b98a5c6 and 4160402.

Files selected for processing: 3

  • packages/provider-cursor/src/server/usageLimits.test.ts
  • packages/provider-cursor/src/server/usageLimits.ts
  • packages/provider-grok/src/server/usageLimits.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

maria-rcks commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

thanks @wookiist. the reported period bounds are the right source for pace and the even-spend marker, including variable-length months. i kept your commits and merged current main into this branch.

i simplified the duration calculation to reuse main's strict period-boundary parser. the same parsed bounds now serve zero-usage inference and duration, so impossible dates cannot produce a misleading pace. no client, contract, or settings changes. i kept your weekly/monthly, invalid-start, and billing-decoding tests, added an impossible start, and updated the existing zero-usage expectations.

verification passed through blacksmith-testbox: the two duration tests fail against main for the missing field; all 26 grok tests pass with the fix; vp run check:changed passes format, lint, knip, graphql generation, affected typechecks (5 packages), and focused tests. the worker needed its shallow snapshot attached to the pinned main commit for the changed-file comparison.

browser evidence uses the real usage page in system chrome with the same fixed weekly billing fixture and clock. each snapshot uses the actual converter from main or this branch. the after capture shows both the pace icon and even-spend marker. this proves rendering, not live account integration. live grok billing credentials and native mobile/desktop clients are unverified on this vm. the existing mocked HTTP decoding test covers the provider read path. both independent reviews approve cdc2312da3a21573b4b7f6a776dba1810b4a3cf3, with no findings. github CI and four preview workflows are action_required with no jobs: a maintainer must approve these fork workflows. the green status contexts do not include those blocked workflows. coderabbit skipped a fresh review due to its review quota. this pr is waiting on human workflow approval, not merge-ready yet.

main: grok weekly allowance without pace or even-spend marker

updated branch: the same allowance with pace and even-spend marker

@wookiist

Copy link
Copy Markdown
Contributor Author

Thanks @maria-rcks for picking this up! Reusing the shared period-boundary parser makes sense, and the extra impossible-start test is a nice addition. Happy to help with anything else if needed.

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed labels Oct 27, 2026
wookiist and others added 2 commits November 9, 2026 04:07
The Cursor usage response carries billingCycleStart, but the adapter only
read billingCycleEnd, so the monthly windows had no windowDurationMins.
Without it the Usage page cannot show the pace badge or the even-spend
marker. Derive the length from end - start, as the Grok adapter does, and
omit it when the start is missing or invalid.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@wookiist wookiist changed the title fix(provider-grok): Grok usage limits show pace and the even-spend line fix(usage): Grok and Cursor usage limits show pace and the even-spend line Nov 8, 2026
@wookiist

wookiist commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

@maria-rcks @juliusmarminge I pushed a follow-up that adds the same fix for Cursor, as discussed in #21896, and merged current main into the branch (no conflicts). Could you take another look?

Both providers are covered by unit tests that need no account: the Grok cases in GrokProvider.test.ts and the Cursor cases in usageLimits.test.ts. The live Cursor response does include billingCycleStart, a 30-day cycle for my account. For the manual check, the Grok screenshots are in the PR description. I did not check the Cursor row on the Usage page itself.

Locally I could only run the Cursor tests after the merge, because pnpm install --frozen-lockfile stops on minimumReleaseAge. So the Grok tests and the typecheck need CI.

Also, the PR has had pr:gate-failed since Oct 27. If a specific gate failed, or CI is waiting for a run approval, please let me know what I should change.

Written by Claude Sonnet 5.5 on behalf of @wookiist.

@juliusmarminge

Copy link
Copy Markdown
Member

Evidence

Real web app; fresh databases; same browser, 1280×800 viewport and light theme. Synthetic upstream responses exercise each commit's unchanged adapters: Grok seven-day period and Cursor thirty-day billing cycle, both halfway elapsed.

Steps on both commits: enable the fixture accounts before startup → pair → Usage → Limits → hover Grok Weekly → hover Cursor Models.

Base omits pace icons, even-spend lines and window percentages. Head shows the icons and halfway lines on all three rows, with 'Even pace — 50% left by now' in both inspected hover panels.

Capture Before After
Commit 034f3ba918 4d0eb0e15e
Grok Weekly Before: Grok lacks pace indicators After: Grok shows pace icon, line and 50% window remaining
Cursor monthly Before: Cursor lacks pace indicators After: Cursor shows pace icon, line and 50% window remaining
Hover recording Before recording After recording

Reproduction files: launcher and interaction steps, settings seed, synthetic upstream responses, Grok CLI fixture.

AI-assisted; verified with the tests and tools listed above.

Not shown:

  • Live Grok/Cursor account sign-in and billing services were not exercised; synthetic credentials and upstream responses made the comparison repeatable.
  • Malformed, missing or reversed billing boundaries were not visually exercised.

@juliusmarminge
juliusmarminge merged commit e2a7814 into pingdotgg:main Nov 11, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Grok usage limits never show pace or the even-spend line

3 participants