Skip to content

feat(usage): redeem Codex reset credits from the Limits tab - #9534

Merged
juliusmarminge merged 8 commits into
mainfrom
feat/codex-reset-credits
Sep 4, 2026
Merged

feat(usage): redeem Codex reset credits from the Limits tab#9534
juliusmarminge merged 8 commits into
mainfrom
feat/codex-reset-credits

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 4, 2026

Copy link
Copy Markdown
Member

Follow-up to #9507, carrying over the reset-credit redemption from #9421.

Codex grants a reset credit when it has rate-limited an account unfairly ("Thanks for using Codex! You've been granted one free rate limit reset."). Redeeming one clears the current 5h/weekly windows. The Limits tab now shows how many are banked and when the next expires, with a confirmed Use a reset credit action.

How it works

  • ServerProviderUsageLimits.resetCredits carries the count and soonest expiry; the Codex probe reads it from the same account/rateLimits/read it already makes.
  • ProviderInstance.consumeResetCredit is a new optional hook — account-level, so it sits beside refreshModels rather than on the thread-routed adapter. The Codex driver implements it over a short-lived app-server (via withCodexAppServerClient, factored out of the status and skills probes which duplicated the setup), then re-probes.
  • Single-flight per instance with one idempotency key kept until Codex reports an outcome, so a retry after a timeout does not open a second attempt.
  • New provider.consumeResetCredit RPC under the operate scope; the outcome (reset / nothingToReset / noCredit / alreadyRedeemed) is shown inline.

Only Codex reports credits today. A provider without the hook gets a clear "does not bank reset credits" error; one without credits shows nothing.

Screenshots

The local Codex row with one banked credit (the same account via the CLIProxyAPI hub above it shows no credit, as expected — the hub does not relay them):

Limits tab with the Codex row showing "1 reset credit banked · next expires in 16d 22h" and a "Use a reset credit" button

Close-up of the row:

Codex row: Weekly 25% used bar, then "1 reset credit banked · next expires in 16d 22h" with the "Use a reset credit" button

Clicking it opens the confirmation; nothing is sent until Use credit:

Confirm dialog: "Use a reset credit? This redeems one credit on your account and clears the current rate-limit windows. It cannot be undone." with Cancel and Use credit

Verification

  • Mapper tests for the credit summary; provider, contract, and Usage page suites pass; typecheck clean.
  • Verified against a real Codex Pro account holding one credit: summary and expiry render, the confirm dialog opens. Not redeemed — that would spend the credit.

Written by Claude Fable 5 via Claude Code; design and single-flight approach from @StiensWout's #9421.


Note

Medium Risk
Redemption spends real account credits over a new RPC; correctness depends on per-account locking and idempotency, though disabled instances and non-Codex providers are rejected explicitly.

Overview
Adds end-to-end redemption of banked Codex rate-limit reset credits from the Limits UI on web and mobile, backed by a new operate-scoped provider.consumeResetCredit RPC.

Contracts and server: ServerProviderUsageLimits can include resetCredits (count + next expiry). Codex probes attach that from account/rateLimits/read. Optional ProviderInstance.consumeResetCredit is implemented for Codex via a scoped app-server call to account/rateLimitResetCredit/consume, then a limits refresh. CodexResetCreditCoordinator serializes redemptions per Codex account directory, reuses one idempotency key until Codex returns an outcome, and times out hung requests. withCodexAppServerClient is extracted so status, skills, and redemption share the same short-lived app-server setup.

Clients: Limits rows show banked credits and a confirmed Use a reset credit action that calls serverEnvironment.consumeResetCredit and surfaces outcomes (reset, nothingToReset, etc.) or errors.

Web usage sources (same PR): Adding/removing CLIProxyAPI hubs and the add dialog target a selected connected environment (with picker when several are connected), gated by operate access—not only the primary environment.

Reviewed by Cursor Bugbot for commit 98f32e6. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add Codex reset-credit redemption from the Usage Limits tab

  • Adds a CodexResetCreditCoordinator service that serializes redemptions per account, reuses the idempotency key on failure, and clears it on success, bounded by a 20-second timeout.
  • Adds the providerConsumeResetCredit WebSocket RPC, scoped to the orchestration operate authorization, which resolves a provider instance, invokes its reset-credit operation, and refreshes the usage snapshot.
  • Maps Codex rate-limit reset-credit data into the provider usage-limit contract with an available count and earliest expiry.
  • Adds reset-credit controls to both web and mobile Usage Limits views, gated by environment operate access, and reworks the web page to scope source add/remove and provider actions to the owning environment.
  • Risk: CodexDriver.create now requires CodexResetCreditCoordinator in its service context; registry and runtime test layers in ProviderInstanceRegistryLive.test.ts, ProviderRegistry.test.ts, and server.ts were updated to provide it, but any out-of-tree provider driver composition will fail to build.

Macroscope summarized 98f32e6.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ The exact PR base did not have a successful artifact. Baseline uses the latest successful main measurement shown below.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.5 KiB 13.7 KiB +227 B (+1.6%) 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.0 KiB −7 B (−0.1%) 7.3 KiB
Codex Live turn WebSocket wire 6.5 KiB 6.7 KiB +234 B (+3.5%) 7.8 KiB
Codex Live turn WebSocket decoded 57.0 KiB 58.5 KiB +1.5 KiB (+2.6%) 66.4 KiB
Codex Live turn messages 8 10 +2 (+25.0%) 21
Claude Total thread wire 13.8 KiB 13.7 KiB −12 B (−0.1%) 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.0 KiB +10 B (+0.1%) 7.3 KiB
Claude Live turn WebSocket wire 6.7 KiB 6.7 KiB −22 B (−0.3%) 7.8 KiB
Claude Live turn WebSocket decoded 59.3 KiB 59.3 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 10 10 0 (0.0%) 21

Baseline: 3e2c1a6 · PR result: 98f32e6 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Comment thread apps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment thread apps/server/src/ws.ts
Comment thread apps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment thread apps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment thread packages/client-runtime/src/state/server.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a new, irreversible Codex account action with server-side coordination, authorization, RPC plumbing, and new web/mobile controls. It also modifies the auth package and broadens environment settings edits, so the production and access-control behavior should receive human review.

You can add or adjust custom eligibility rules. Learn more.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backend behavior added here (driver-level reset-credit redemption plus the new provider.consumeResetCredit RPC) is currently covered only by the pure codexResetCreditsToContract unit test. Consider a focused test for the redemption path — single-flight under the semaphore, idempotency-key reuse across a failed attempt, and the follow-up snapshot.refresh — using the existing child-process test layers (see apps/server/src/provider/Layers/CodexProvider.test.ts / Drivers/AntigravityDriver.test.ts), so the external app-server is the only thing stubbed.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/ws.ts
Comment thread apps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment thread apps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment thread apps/server/src/provider/Layers/codexResetCredit.ts Outdated
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026
Comment thread apps/web/src/components/usage/UsageLimits.tsx
Comment thread apps/web/src/components/usage/UsageLimits.tsx
juliusmarminge and others added 5 commits September 3, 2026 18:49
Codex grants a reset credit when it has rate-limited an account unfairly;
redeeming one clears the current windows. The credit count and soonest
expiry now ride on the provider's usageLimits, and a confirmed "Use a
reset credit" action on the Limits tab redeems one.

Redemption is an account-level operation, so it lives on ProviderInstance
(beside refreshModels) rather than on the thread-routed adapter. The Codex
driver opens a short-lived app-server through the opener the status and
skills probes now share, sends account/rateLimitResetCredit/consume, and
re-probes so the cleared windows show. It is single-flight per instance
and keeps one idempotency key until Codex reports an outcome, so a retry
after a timeout re-sends the same attempt.

Design from #9421.

Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
- Redemption coordinates per account (the driver's continuation key), not
  per instance: two Codex instances sharing a home now queue on one lock
  with one pending idempotency key instead of spending two credits.
- The scoped app-server request is bounded at 20s so a hung process
  cannot hold the account lock; the kept key makes the retry safe.
- The idempotency key comes from the Crypto service the driver already
  requires, not node:crypto.
- The RPC rejects disabled instances and passes the driver error through
  as the ProviderSetupError cause.
- A failed re-probe after redemption is reported instead of silently
  leaving the old credit count on the snapshot.
- The client single-flight key is JSON-encoded so ids cannot collide.
- Focused tests for key reuse across a failed attempt, account-level
  serialisation, and account independence.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Mobile's Limits card gains the same reset-credit summary and a confirmed
"Use a reset credit" action, through the native alert rather than a
custom dialog. The web view's add-hub button moves from below every row
to a "Usage sources" header at the top of the Limits tab, where a user
looking for it will actually look.

Co-Authored-By: Claude Code <noreply@anthropic.com>
…rvice

Two review findings on the previous fix. The account lock was keyed on
the continuation key, which is the shared Codex home; an auth-overlay
instance keeps its own auth.json under effectiveHomePath, so two signed-in
accounts could share a lock and a pending idempotency key. It now keys
on the directory that actually holds auth.json.

The coordination state also lived in a module-level Map. It is now a
Context.Service (CodexResetCreditCoordinator) that CodexDriver.create
acquires from its env, with a get-or-create that cannot install two
locks for one account, and a self-contained layerTest so tests get
isolation from a fresh layer instead of a reset hook.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The add-hub button and the per-source Remove were gated on
usePrimarySettingsAvailable(), which answers "is there a primary
environment or am I not a hosted app". A T3 Connect client with no
primary anchored therefore never saw them, though writing a source is a
server.updateSettings call that only needs the operate scope, like every
other provider control.

Both now target a connected environment directly: the primary when there
is one, else the first connected environment, with a picker when several
are connected. Remove is bound to the environment the source lives in.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Comment thread apps/web/src/components/usage/UsageLimits.tsx
… its target

Add hub and Remove now check the environment's operate scope the way
Settings → Providers does, so a client that lacks it is not offered a
write the server will reject. The add-hub dialog is keyed on its target
environment: if that target disconnects or the primary changes while the
dialog is open, a fresh dialog mounts empty instead of carrying a typed
management key over to a different environment.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@juliusmarminge
juliusmarminge force-pushed the feat/codex-reset-credits branch from 6d8896e to f790a41 Compare September 4, 2026 01:51
Comment thread apps/web/src/components/usage/UsageLimits.tsx Outdated
…ad-only

Gating the whole header on the target's operate access hid the picker
along with the button, so a read-only default left no way to choose an
operable environment. The picker now stays whenever several are
connected; only the button follows the picked target, disabled with a
reason when that target cannot be written.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but a cloud agent failed to start.

Reviewed by Cursor Bugbot for commit 3e6727c. Configure here.

Comment thread apps/server/src/provider/Drivers/CodexDriver.ts
…ed reason

The post-redeem check looked for a probeFailed reason on the refreshed
snapshot, but the probe resolver republishes the last good limits when a
probe fails and bars already exist, so that reason never appeared and a
failed confirmation reported success with stale bars. The check now
requires the published checkedAt to advance past the pre-redemption
value.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@juliusmarminge
juliusmarminge merged commit 1641b4a into main Sep 4, 2026
28 checks passed
@juliusmarminge
juliusmarminge deleted the feat/codex-reset-credits branch September 4, 2026 02:14
sheehanmunim added a commit to munimtechnologies/mtcode that referenced this pull request Sep 4, 2026
…ity ACP, browser import, settings reorg, limits tab)

Brings the fork up to upstream/main fee2e0f. Highlights: Google Antigravity
via the official ACP agent (pingdotgg#9348) + model manifest refreshes, browser-cookie
import (Chrome/Edge/Brave/Firefox, pingdotgg#7255/pingdotgg#7260/pingdotgg#7261), settings page reorg
(pingdotgg#9354), Codex/Claude subscription Limits tab (pingdotgg#9507, pingdotgg#9534), context
compaction command (pingdotgg#9293), async Codex questions (pingdotgg#9512), full-access
OpenCode threads skip approvals (pingdotgg#9282), project icons default (pingdotgg#9457).

Unification decisions (keep-both unless noted):
- BrowserImport: upstream implementation wins (Linux libsecret, Windows DPAPI
  unwrap, writeCookies); fork's Safari engine ported in (jar definition,
  candidate path, profile listing, running check, count skip, import branch,
  FullDiskAccess wizard step + SafariCookies kept, domain widened only for
  dotted hosts).
- Antigravity: upstream ACP provider/adapter/driver/textgen win; fork branding
  ported (providerDisabledMessage), AntigravitySettings unified (fork fields +
  upstream auth fields; enabled stays default-on).
- contracts/model: Antigravity defaults follow upstream's manifest model.
- ClaudeAdapter compact_boundary: fork's resolve helper kept, renamed to
  upstream's compactedUsage to match downstream.
- Claude capabilities probe: fork's timeout races kept; upstream's raw usage
  fetch added under the same timeout so stalled usage still degrades.
- Codex provider: upstream's withCodexAppServerClient + enriched rate-limits
  probe win (fork title branding already inside buildCodexInitializeParams).
- ProviderCommandReactor: fork goal-continuation + correction-aware first-turn
  kept; upstream compact-command exclusion added.
- OpenCodeAdapter ask path: fork's pendingGate/acceptingRequests gate kept;
  upstream full-access autoReply + terminal guard + emitUnsafe added.
- makeManagedServerProvider: fork probe-timeout protection kept; upstream
  usage-limits reconciliation applied to the checked snapshot.
- Manager.ts preview CDP: fork reuse-if-attached + detach resilience kept;
  upstream wcDebugger hardening applied.
- mobile threadSyncPhase pill dropped (upstream ThreadDetail redesign covers
  loading/sync presentation); outbox deliveryMode + goal handling kept.
- Usage: fork client-version projection kept; upstream pricing()/refreshRates
  adopted on both clients.
- Settings: fork sections (MT Teams+badge, voice, notifications, account
  sign-in) kept; upstream reorg (ids, submenus, behaviour section) adopted.
- README: fork copy kept; Antigravity added to provider lists.
- Cursor skill test macOS /var-vs-/private/var path failure is pre-existing
  upstream breakage, unrelated to this merge.

Fork guard script OK.
jmclaren7 added a commit to mclaren-data-systems/t3code that referenced this pull request Sep 4, 2026
Second sync of 2026-09-04: 108 upstream commits (9c9ae3d..c8f77e0), 32 of
33 fork commits replayed.

- Entry 22's server half is superseded by upstream's Limits tab work
  (pingdotgg#9507, pingdotgg#9534, pingdotgg#9584); its web half is re-derived onto
  ServerProvider.usageLimits and the fork's server files are dropped.
- Entry 14 declines upstream's two new workflows (windows-tests.yml on a
  Blacksmith runner, cursor-hygiene-webhook.yml needing Cursor secrets).
- Entry 7's history store moves to upstream's createDeferredStorage; entry
  19's colour ramp is read as colors[0] by upstream's new UsageLimits.tsx.
- FORK.md section 2 records the rebase; every entry's check note and the
  superseded table move to c8f77e0; README banner refreshed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyxmS9VVThN5D4JqXrB4CY
henrychu04 added a commit to henrychu04/t3code-coder that referenced this pull request Sep 5, 2026
* fix(web): send cited messages with Cmd+Enter (pingdotgg#9307)

* fix(web): preserve explicit preview navigation URLs (pingdotgg#8902)

* fix(web): prevent loading ssh environments from overriding navigation (pingdotgg#9168)

* fix(mobile): skip unsupported shared settings targets (pingdotgg#9381)

* fix(web): avoid duplicate Antigravity install status (pingdotgg#9419)

* fix(composer): mute fast icon when collapsed (pingdotgg#9451)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): unify skeleton loading animations on one pulse (pingdotgg#9448)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): prioritize authored pull requests (pingdotgg#9453)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): make project icons the default (pingdotgg#9457)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(server): reuse pr state when settling threads (pingdotgg#9459)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): keep agent images collapsed (pingdotgg#9460)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): banner buttons no longer expand the resting composer (pingdotgg#9452)

* fix(web): stop clipping the traits chevron on long Codex effort labels (pingdotgg#9433)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): make right panel tabs easier to scroll (pingdotgg#9461)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): render transparent previews on white (pingdotgg#9463)

* fix(mobile): show loading and syncing in the working pill (pingdotgg#9466)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix(server): keep a/ and b/ prefixes in rendered git patches (pingdotgg#9438)

* fix(server): full-access OpenCode threads no longer ask for approvals (pingdotgg#9282)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>

* fix(web): reuse pull request list data while loading (pingdotgg#9467)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* feat(web): let users turn off composer collapse on blur and scroll (pingdotgg#9469)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(web): move workflow approval beside checks (pingdotgg#9465)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(desktop): refresh generated annotation styles (pingdotgg#9488)

* fix(web): let the PR reviewer and label search boxes take keystrokes (pingdotgg#9479)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(web): dont collapse composer when interacting with bottom row (pingdotgg#9490)

* fix(desktop): restore second-press quit fallback (pingdotgg#9485)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): keep opencode icon hollow in collapsed composer (pingdotgg#9492)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): keep agent browser preview visible (pingdotgg#9484)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(mobile): keep the machine glyph next to the environment label (pingdotgg#9486)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix(mobile): let back swipe pop from horizontal scroll edges (pingdotgg#9493)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(antigravity): discover legacy workspace skills (pingdotgg#9410)

Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>

* fix(mobile): resolve Antigravity provider icon and normalize driver matching (pingdotgg#9495)

* fix(antigravity): forward Google sign-in URLs from browser helper (pingdotgg#9425)

* feat(desktop): import browser cookies into a profile (pingdotgg#7255)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(desktop): import from Chrome, Edge, Brave, Vivaldi, Opera, Arc and Firefox (pingdotgg#7260)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(desktop): resolve Chromium cookie keys on Linux (pingdotgg#7261)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(antigravity): allow slow runtime startup during setup (pingdotgg#9510)

* fix(antigravity): keep model choices up to date (pingdotgg#9511)

* fix(antigravity): handle native sign-in URLs on stderr (pingdotgg#9514)

* fix(antigravity): update managed runtime to 1.1.1 (pingdotgg#9509)

* fix(desktop): address the browser import review left over from the stack (pingdotgg#9516)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com>

* feat(antigravity): show subagent calls and results (pingdotgg#9515)

* fix(web): let paste expand a resting composer (pingdotgg#9498)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(web): keep the composer open while selecting timeline text (pingdotgg#9499)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(web): return focus to the composer after closing a media preview (pingdotgg#9513)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(server): keep events during thread subscription startup (pingdotgg#9521)

* chore: forward issue/PR/discussion events to Cursor hygiene (pingdotgg#9518)

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>

* fix(auth): keep pairing credentials out of access read models (pingdotgg#9523)

* chore: drop comment events from Cursor hygiene forwarder (pingdotgg#9527)

* feat(codex): support async questions (pingdotgg#9512)

* fix(web): keep right panel controls clickable (pingdotgg#9517)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* feat(usage): show Codex and Claude subscription limits on a Limits tab (pingdotgg#9507)

Users on Codex or Claude Code subscriptions could not see how much quota was left or when it resets without leaving T3 Code. A user whose CLIs route through a CLIProxyAPI hub could not see it at all.

Each driver now returns `usageLimits` on its own snapshot (Codex from `account/rateLimits/read`, Claude from the SDK's `get_usage`), adapters normalise turn-driven rate-limit events at the boundary, and a driver-blind ingestion layer folds them onto the owning instance. The Usage page gains a Limits tab (mobile a card) with a bar per window, elapsed marker, pace, and reset countdown. CLIProxyAPI hubs can be added as read-only usage-limit sources; their accounts show badged "via CLIProxyAPI" with emails blurred.

Distilled from pingdotgg#1732 (server model, provider rows) and pingdotgg#9421 (Limits tab, window bars, pace maths). Closes pingdotgg#228.

Co-authored-by: Aditya Mer <101453576+Aditya190803@users.noreply.github.com>
Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>

* feat(web): reorganize settings pages (pingdotgg#9354)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(server): settle branch threads immediately on pull request merge (pingdotgg#9528)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(server): back off relay client restarts after rapid exits (pingdotgg#8788)

* fix(codex): accept rate limit errors on thread resume (pingdotgg#8897)

* fix(desktop): preview CDP sessions no longer hard-crash the app (pingdotgg#9068)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Fix worktree removal timing out on large install trees (pingdotgg#3902)

* fix(web): settle the resting composer layout with a pixel of slack (pingdotgg#9482)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(web): keep automatic project icons consistent (pingdotgg#9535)

* fix(server): include SQLite conditions in persistence errors

Include SQLite conditions and schema issue tags without copying query data.

Continue @Sy-D's [pingdotgg#4837](pingdotgg#4837). Add the missing Bun error codes and test the real SQL client.

Created with GPT-6 Astra (preview) in Codex.

Co-authored-by: Sy-D <8460326+Sy-D@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* fix(dev): keep shared dev reloads and hot updates working (pingdotgg#9543)

* feat(providers): add context compaction command (pingdotgg#9293)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(mobile): keep store screenshots free of system banners and show dictation (pingdotgg#9548)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix(web): restore composer controls as space becomes available (pingdotgg#9539)

* fix(web): measure collapsed model labels at their visible width (pingdotgg#9540)

* fix(web): close composer menus when their controls hide (pingdotgg#9541)

* fix(web): thread error banner no longer shifts the chat (pingdotgg#9473)

* fix(server): reveal normalized paths in File Explorer (pingdotgg#9551)

* feat(marketing): fresh screenshot and floating marks on the homepage (pingdotgg#9547)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

* feat(usage): redeem Codex reset credits from the Limits tab (pingdotgg#9534)

Follow-up to pingdotgg#9507, carrying over the reset-credit redemption from pingdotgg#9421.

Codex grants a reset credit when it has rate-limited an account unfairly (`"Thanks for using Codex! You've been granted one free rate limit reset."`). Redeeming one clears the current 5h/weekly windows. The Limits tab now shows how many are banked and when the next expires, with a confirmed **Use a reset credit** action.

## How it works

- `ServerProviderUsageLimits.resetCredits` carries the count and soonest expiry; the Codex probe reads it from the same `account/rateLimits/read` it already makes.
- `ProviderInstance.consumeResetCredit` is a new optional hook — account-level, so it sits beside `refreshModels` rather than on the thread-routed adapter. The Codex driver implements it over a short-lived app-server (via `withCodexAppServerClient`, factored out of the status and skills probes which duplicated the setup), then re-probes.
- Single-flight per instance with one idempotency key kept until Codex reports an outcome, so a retry after a timeout does not open a second attempt.
- New `provider.consumeResetCredit` RPC under the operate scope; the outcome (`reset` / `nothingToReset` / `noCredit` / `alreadyRedeemed`) is shown inline.

Only Codex reports credits today. A provider without the hook gets a clear "does not bank reset credits" error; one without credits shows nothing.

## Screenshots

The local Codex row with one banked credit (the same account via the CLIProxyAPI hub above it shows no credit, as expected — the hub does not relay them):

![Limits tab with the Codex row showing "1 reset credit banked · next expires in 16d 22h" and a "Use a reset credit" button](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2897db5e357f12b3/credits-tab.png)

Close-up of the row:

![Codex row: Weekly 25% used bar, then "1 reset credit banked · next expires in 16d 22h" with the "Use a reset credit" button](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/0e80f9114cab8f36/credits-row.png)

Clicking it opens the confirmation; nothing is sent until **Use credit**:

![Confirm dialog: "Use a reset credit? This redeems one credit on your account and clears the current rate-limit windows. It cannot be undone." with Cancel and Use credit](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dc728580889ef1fe/credits-confirm.png)

## Verification

- Mapper tests for the credit summary; provider, contract, and Usage page suites pass; typecheck clean.
- Verified against a real Codex Pro account holding one credit: summary and expiry render, the confirm dialog opens. **Not redeemed** — that would spend the credit.

Written by Claude Fable 5 via Claude Code; design and single-flight approach from @StiensWout's pingdotgg#9421.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Redemption spends real account credits over a new RPC; correctness depends on per-account locking and idempotency, though disabled instances and non-Codex providers are rejected explicitly.
> 
> **Overview**
> Adds **end-to-end redemption of banked Codex rate-limit reset credits** from the Limits UI on web and mobile, backed by a new operate-scoped `provider.consumeResetCredit` RPC.
> 
> **Contracts and server:** `ServerProviderUsageLimits` can include `resetCredits` (count + next expiry). Codex probes attach that from `account/rateLimits/read`. Optional `ProviderInstance.consumeResetCredit` is implemented for Codex via a scoped app-server call to `account/rateLimitResetCredit/consume`, then a limits refresh. `CodexResetCreditCoordinator` serializes redemptions per Codex account directory, reuses one idempotency key until Codex returns an outcome, and times out hung requests. `withCodexAppServerClient` is extracted so status, skills, and redemption share the same short-lived app-server setup.
> 
> **Clients:** Limits rows show banked credits and a confirmed **Use a reset credit** action that calls `serverEnvironment.consumeResetCredit` and surfaces outcomes (`reset`, `nothingToReset`, etc.) or errors.
> 
> **Web usage sources (same PR):** Adding/removing CLIProxyAPI hubs and the add dialog target a **selected connected environment** (with picker when several are connected), gated by operate access—not only the primary environment.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 98f32e6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(server): find newly opened pull requests after agent turns (pingdotgg#9125)

Refresh missing PR associations after agent turns on the thread's current branch. Preserve background policy, known PR caches, and failed-lookup backoff. Serialize status loads and refreshes to prevent stale responses from hiding a PR. Find branches pushed under their own name while still tracking the default branch.

Original work by Theo Browne with Claude Fable 5.1 in Claude Code. Takeover fixes created with GPT-6 Astra (preview) in Codex.

Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

* ci: add on-demand Windows test workflow (pingdotgg#9538)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix(web): simplify expanded tool details (pingdotgg#9549)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): keep the last message visible when the resting composer expands (pingdotgg#9553)

Scrolling a long thread to the end with the composer at rest landed flush
against the short composer. The expansion that followed then covered the
last rows, because the timeline reserves only the live overlay height and
does not move for footer growth.

The timeline now keeps the expanded composer's height clear while the
composer rests, so expanding it again changes nothing above the composer.
The composer reports its resting flag from a layout effect and publishes a
fresh overlay height whenever that flag changes, so the reservation is
always computed from a height that belongs to the same layout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(web): fix flaky startup and Tailwind tests (pingdotgg#9558)

* fix(web): keep codex restart responses continuous (pingdotgg#9560)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): make settings sidebar sub-section buttons full width (pingdotgg#9562)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix(web): render settings sidebar immediately (pingdotgg#9563)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* chore: vouch august contributors (pingdotgg#9557)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): stabilize right panel transitions (pingdotgg#9554)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix: better shell syntax handling for labels (pingdotgg#9371)

* fix(web): align the sidebar wordmark by baseline (pingdotgg#9578)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(antigravity): keep subagent batches active after launch (pingdotgg#9579)

* fix(mobile): render workspace images in markdown file previews (pingdotgg#8769)

* fix(usage): deduplicate CLI proxy subscription accounts (pingdotgg#9584)

* fix(web): bound disconnected send toasts (pingdotgg#9592)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(desktop): restore panel titlebar interactions (pingdotgg#9591)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(connect): refresh authorization without disconnecting (pingdotgg#9582)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): show context meter in compact composer (pingdotgg#9430)

* fix(pull-requests): refresh data after thread turns (pingdotgg#9496)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web): render draft PRs in gray (pingdotgg#9537)

* refactor(web): move usage provider controls to settings (pingdotgg#9599)

* fix: show idle subagent batches without completion marks (pingdotgg#9616)

* fix(web): group image views like other tool calls (pingdotgg#9597)

Co-authored-by: Claude Code <noreply@anthropic.com>

* fix: preserve tool icons on failed calls (pingdotgg#9606)

* fix(connect): diagnose incomplete headless server setup (pingdotgg#9602)

* fix(web): keep command palette above composer menus (pingdotgg#9613)

* fix(web): snooze menu no longer overlaps thread details (pingdotgg#9601)

* fix(web): match composer pull request state icons (pingdotgg#9375)

* fix(server): load OpenCode workspace skills via SDK to avoid 64KB CLI pipe truncation (pingdotgg#9585)

* fix(web): mute sidebar branch name to match worktree icon (pingdotgg#9622)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* fix(web,mobile): fold context compaction under settled turn folds (pingdotgg#9623)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

* feat(mobile): make chat text selectable on Android (pingdotgg#8779)

Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>

* fix(web): toggle a single stashed prompt with Cmd+S (pingdotgg#9644)

Cmd+S opened the stash menu even when the composer was empty and only one prompt was stashed. It now restores that prompt directly, so repeated presses toggle between the draft and stash.

Multiple entries and images that are still saving open the menu. The stash badge still opens the menu.

Validation: 94 focused stash, shortcut, and attachment tests pass. Web typecheck and formatting pass. Targeted lint has no new warnings or errors. Browser checks were skipped at Theo's request.

Original implementation by Theo Browne. No code changes were needed during the takeover audit.

Audited with GPT-6 Astra (preview) in Codex.

* fix(server): prevent duplicate desktop clients after restart

Replace stale local desktop sessions in one transaction. Preserve paired clients and browser sessions, and keep the previous credential valid if replacement fails.

Closes pingdotgg#6283.

Original implementation by seeb1337. Reviewed and verified with GPT-6 Astra (preview) in Codex.

Co-authored-by: seeb1337 <63622047+seeb1337@users.noreply.github.com>
Co-authored-by: Theo Browne <me@t3.gg>

* fix(web): resume Antigravity threads without repeated sign-in (pingdotgg#9647)

Allow Antigravity threads to resume while saved Google sign-in is unchecked after a server restart. Keep confirmed authentication failures and installation errors visible.

Validated with 136 focused tests, web typecheck, targeted lint, and CI. Browser verification was omitted at the maintainer's request.

Created with GPT-6 Astra (preview) in Codex.

* feat(mobile): paste the phone clipboard into the terminal (pingdotgg#9199)

Co-authored-by: Jake Leventhal <jakeleventhal@me.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>

* feat(web): show which sidebar threads hold an unsent draft (pingdotgg#9658)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

* fix(server): unblock OpenCode approvals and stop (pingdotgg#9653)

OpenCode could show an Approval badge with no controls, appear stuck on TodoWrite, and keep showing a running turn after Stop.

- Show every permission, including old saved requests. Keep failed replies retryable and close completed requests even when reply events are lost.
- Keep OpenCode output pipes drained and automatic replies out of the event loop. Handle disconnects, reconnects, and confirmed stops without stale requests or running states.
- Show native task progress and command results. Do not treat TodoWrite or approval history as file edits or executed commands.
- Ignore late aborts and task updates after a turn finishes.

Fixes pingdotgg#4795
Fixes pingdotgg#7113
Fixes pingdotgg#5760

Created with GPT-6 Astra (preview) in Codex. Reviewed and merged with Claude Fable 5.1 in Claude Code.

* fix(desktop): quit immediately on a second shortcut press (pingdotgg#9657)

* fix(server): update Claude Agent SDK to 0.3.260 (pingdotgg#9135)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

* perf(server): stop loading message bodies for thread summaries (pingdotgg#9662)

* perf(web): speed up terminal snapshots (pingdotgg#9663)

* Complete upstream sync adaptations and validate Claude authentication

* Fix reviewed Coder sync regressions and add focused coverage

* Include orchestration regression suites in Coder tests

---------

Co-authored-by: Exotic <118054752+extoci@users.noreply.github.com>
Co-authored-by: Yukun Shan <92423096+nateEc@users.noreply.github.com>
Co-authored-by: oliver <97427849+flamboh@users.noreply.github.com>
Co-authored-by: Simone <lucenz@proton.me>
Co-authored-by: Rakshith Bhat <88523594+RakshithBhat03@users.noreply.github.com>
Co-authored-by: maria <maria@kuuro.net>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Zortos <zortosdev@proton.me>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Igor Makowski <56691628+Mnigos@users.noreply.github.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: Invictine <72551038+Invictine@users.noreply.github.com>
Co-authored-by: WellyngtonF <59291417+WellyngtonF@users.noreply.github.com>
Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
Co-authored-by: Aditya Mer <101453576+Aditya190803@users.noreply.github.com>
Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Derek Trimm <275381468+derektrimm@users.noreply.github.com>
Co-authored-by: Seth Webster <sethwebster@gmail.com>
Co-authored-by: Jake Leventhal <jakeleventhal@me.com>
Co-authored-by: Matheus Timbó Pereira <matheusfild4@hotmail.com>
Co-authored-by: Sy-D <8460326+Sy-D@users.noreply.github.com>
Co-authored-by: Yash Singh <saiansh2525@gmail.com>
Co-authored-by: Dara Adedeji <76637177+SunkenInTime@users.noreply.github.com>
Co-authored-by: Guilherme Vieira <46866023+GuilhermeVieiraDev@users.noreply.github.com>
Co-authored-by: Guillermo Casanova <75276669+Gigioxx@users.noreply.github.com>
Co-authored-by: Barry <43803274+BarryHenryJr@users.noreply.github.com>
Co-authored-by: seeb1337 <63622047+seeb1337@users.noreply.github.com>
Co-authored-by: Lars Nieuwenhuis <35393046+lnieuwenhuis@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant