Notify when a new earned limit reset is banked (1.1.0) #8

Merged
claude merged 7 commits from oss-oo/banked-reset-notifications into main 2026-10-27 23:03:12 +00:00
Member

Feature for 1.1.0, asked by Claudiu: besides the 7d Codex refresh, notify when a new banked (earned) Codex limit reset arrives.

Data model (app-server schema of Codex CLI 0.165): rateLimitResetCredits carries an authoritative availableCount and credits with id, status, expiresAt and grantedAt; the list may be capped, null means only the count is known, and the whole summary can be missing.

  • The helper marks whether the count was reported at all (resetCountKnown; a missing summary still reads as a placeholder 0). Replays never carry the flag.
  • The applet keeps a reset bank in memory: the last real fetch that reported a count (a fetch without a summary keeps it) and the credit IDs real fetches have listed; a sign-in loss forgets it. findBankedResets() reports a grown count; where the list is complete, only credits no earlier fetch listed count, and the applet's own pending redemption never does, so a credit back from a failed redemption stays silent. A capped or count-only list leaves the count to decide. Never on the first fetch, after a reload or from a replay; each increase once. No credit ID is ever stored.
  • Same switches and delivery as the 7d refresh (all-models and Codex 7d switches; "Codex limit reset banked", "Limit resets available: N"); real plural forms (_n via dngettext); settings tooltips, README, packaging notes, CHANGELOG and the translation template updated. Known limit, documented: a sign-in change between two refreshes that the applet never saw can announce the other account's credits.
  • Follow-ups from the fifth review of #7: distinct theme-read failures are each reported once; the corner's repaint handler is tested; capture.py reads both manifests before writing either, with unit tests.

Validation: make verify green (74 Python tests), all suites green under clock shifts of +1 h, +4 d, +30 d and +1 y (one load flake in a pre-existing transport timing test, three green reruns), 18 README screenshots recaptured, 121/121 baselined mutants, two independent review rounds with every finding fixed (round 1: the grant-time design → seen IDs; round 2: pending redemption across reloads, baseline and seen IDs move together, plural count cap, test gaps).

🤖 Generated with Claude Code

Feature for **1.1.0**, asked by Claudiu: besides the 7d Codex refresh, notify when a new banked (earned) Codex limit reset arrives. **Data model** (app-server schema of Codex CLI 0.165): `rateLimitResetCredits` carries an authoritative `availableCount` and `credits` with `id`, `status`, `expiresAt` and `grantedAt`; the list may be capped, `null` means only the count is known, and the whole summary can be missing. - The helper marks whether the count was reported at all (`resetCountKnown`; a missing summary still reads as a placeholder 0). Replays never carry the flag. - The applet keeps a reset bank in memory: the last real fetch that reported a count (a fetch without a summary keeps it) and the credit IDs real fetches have listed; a sign-in loss forgets it. `findBankedResets()` reports a grown count; where the list is complete, only credits no earlier fetch listed count, and the applet's own pending redemption never does, so a credit back from a failed redemption stays silent. A capped or count-only list leaves the count to decide. Never on the first fetch, after a reload or from a replay; each increase once. No credit ID is ever stored. - Same switches and delivery as the 7d refresh (all-models and Codex 7d switches; "Codex limit reset banked", "Limit resets available: N"); real plural forms (`_n` via dngettext); settings tooltips, README, packaging notes, CHANGELOG and the translation template updated. Known limit, documented: a sign-in change between two refreshes that the applet never saw can announce the other account's credits. - Follow-ups from the fifth review of #7: distinct theme-read failures are each reported once; the corner's repaint handler is tested; `capture.py` reads both manifests before writing either, with unit tests. Validation: `make verify` green (74 Python tests), all suites green under clock shifts of +1 h, +4 d, +30 d and +1 y (one load flake in a pre-existing transport timing test, three green reruns), 18 README screenshots recaptured, 121/121 baselined mutants, two independent review rounds with every finding fixed (round 1: the grant-time design → seen IDs; round 2: pending redemption across reloads, baseline and seen IDs move together, plural count cap, test gaps). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude agent added 3 commits 2026-10-27 22:28:45 +00:00
Claudiu's request: besides the 7d Codex refresh, notify when a new banked
Codex reset arrives. The app-server protocol (Codex CLI 0.165 schema)
reports the bank as rateLimitResetCredits: an authoritative availableCount,
and credits that each carry a grantedAt time; the list may be capped, and
null means only the count is known.

- The helper marks whether the backend reported the count at all
  (resetCountKnown; a missing summary still reads as a placeholder 0) and
  keeps each listed credit's grantedAt. Replays never carry the flag.
- findBankedResets() reports a grown count between two real fetches that
  both reported one. Where the list is complete, only credits granted since
  the previous fetch (ten minutes of clock skew allowed) count, so a credit
  that came back from a failed redemption stays silent; a capped or
  count-only list leaves the count to decide.
- The notification ("Codex limit reset banked", "Limit resets available:
  N") uses the same switches and delivery as the 7d refresh; the settings
  tooltips, README, packaging notes, changelog and translation template say
  so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A theme-read failure is reported once per distinct message instead of
  once per kind, so a later, different failure is still logged.
- Tests run the corner's repaint handler against missing, empty and
  unreadable menus (it never throws and always releases its Cairo context)
  and cover the surface warning.
- capture.py reads both manifests before writing either, names an
  unreadable one, keeps only .png names with a spec, and its manifest
  preparation is a function with its own unit tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recapture the README screenshots at 6b54e01
All checks were successful
Checks / Functional checks (pull_request) Successful in 42s
9f3c461c9d
All 18 images from 6b54e01 in the private Mint-Y-Dark-Aqua session; only
clock-relative text differs from the 4358a87 set (the new settings tooltips
do not show in the notifications page capture).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The independent review of #8 found that a credit granted shortly before a
fetch could be announced twice: a count dip while it was being redeemed and
its return within ten minutes both passed the grant-time filter. Grant times
also tied the result to the local clock.

- The applet keeps its reset bank in memory: the last real fetch that
  reported a count as the baseline (a fetch without a reset summary keeps
  it) and the credit IDs real fetches have listed. Where the backend lists
  every available credit, only an ID no earlier fetch listed counts; a
  capped or count-only list leaves the count to decide. A sign-in loss
  forgets the bank; no credit ID is ever stored.
- The helper no longer passes grantedAt, which nothing reads now.
- The title uses real plural forms (dngettext, extracted as _n).
- Tests run the review's sequences (dip and return, 1-2-1-2, a missing
  summary between two counts, a late-visible grant), deliver banked events
  through _showUsageNotifications, pin the switch tooltips, and cover the
  sign-in loss; the warning set is bounded.
- Docs name the all-models and Codex 7d switches and say when the count
  alone decides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recapture the README screenshots at c1c1aa2
All checks were successful
Checks / Functional checks (pull_request) Successful in 42s
031c85c80c
All 18 images from c1c1aa2 in the private Mint-Y-Dark-Aqua session; only
clock-relative text differs from the 6b54e01 set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The credit of the applet's own pending redemption (kept in the reset
  journal across reloads) counts as seen, so a failed redemption bringing
  it back after a reload stays silent.
- Only a fetch that reported a count updates the bank: baseline and seen
  IDs move together, so a list without a count cannot hide a later grant.
- dngettext gets a count capped at a million (it takes an unsigned 64-bit
  value), so an absurd count cannot break the refresh.
- The changelog says the protection holds within a session and that a
  sign-in change the applet never saw can still announce the other
  account's credits.
- Tests: the bank keeps learning while its notifications are off, the
  pending-redemption credit after a reload, a list without a count, and a
  real catalog with plural forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recapture the README screenshots at 0da9257
All checks were successful
Checks / Functional checks (pull_request) Successful in 41s
1a7e608724
All 18 images from 0da9257 in the private Mint-Y-Dark-Aqua session; only
clock-relative text differs from the c1c1aa2 set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent merged commit 4113430c0c into main 2026-10-27 23:03:12 +00:00
claude agent deleted branch oss-oo/banked-reset-notifications 2026-10-27 23:03:12 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OSS-Singularity/cinnamon-chatgpt-usage!8
No description provided.