Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell): AiUsageIndicator recognizes resetKind 'weekly' + resetsAt - #7374
Merged
Conversation
…tsAt The free plan's AI quota moved to a rolling 7-day window (cloud PR #1852), which added `resetKind: 'weekly'` to the usage endpoint. AiUsageIndicator only knew 'daily'/'monthly' and fell through to no reset copy for a weekly meter. It now renders "Resets in N days" (or N hours inside the final day), derived from the endpoint's `resetsAt` — never guessed client-side — with new @object-ui/i18n keys (base + _one/_other plural family, all ten packs). An unrecognized resetKind still fails soft: no crash, no reset line. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
CI lint caught `react-hooks/purity` (error): `weeklyResetLabel` called `Date.now()` directly during render. The "now" read now lives in a `useState<number | null>(null)` populated by a mount effect (refreshed every 60s while the popover's host stays mounted); the render body only reads that state and does pure day/hour math from it. `now === null` (the one frame before the effect fires) renders no reset line, same as any other not-yet-known input on this component. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#7371
Summary
AiUsageIndicator(packages/app-shell/src/layout/AiUsageIndicator.tsx) now recognizesthe free plan's new
resetKind: 'weekly'and itsresetsAt, added by cloud PR #1852(
ai-usage-endpoint-plugin.ts:UsageResetKindgained'weekly';resetsAt: string | nullalready existed on this side, unchanged in shape).Before this change a
weeklymeter fell through to the unrecognized-kind path — nocrash, but the popover silently showed no reset line at all next to a live progress
ring. It now renders "Resets in N days" (or "Resets in N hours" once inside the final
day), computed from
resetsAt.What changed
packages/app-shell/src/hooks/useAiUsage.ts—AiUsageResetKindgains'weekly'.resetsAtwas alreadystring | null; only the doc comment was extended to state theweekly contract (null while nothing is counted yet).
packages/app-shell/src/layout/AiUsageIndicator.tsx—resetLabelnow returnsstring | null:'daily'/'monthly'unchanged,'weekly'computes days/hours fromresetsAt(contract-first — never re-derived or guessed client-side;resetsAt: nullrenders nothing), and any unrecognized
resetKind(a future backend value thisbuild doesn't know yet) also renders nothing — fail-soft, matching the file's existing
"missing endpoint degrades to no widget" posture. D5 preserved: only days/hours are
ever rendered, never a token count.
packages/i18n/src/locales/*.ts(all ten packs) — two new keys,console.ai.usage.resetsWeeklyDays/resetsWeeklyHours, each a real i18next pluralfamily (base +
_one+_other) so every pack resolves in its own language ratherthan falling back to English at plural counts the pack didn't enumerate
(
all-locales-key-parity.test.ts's base-key rule).packages/app-shell/src/layout/__tests__/AiUsageIndicator.test.tsx— covers the twoweekly branches (days / hours), the
resetsAt: nullfallback, and an unrecognizedresetKindfallback (asserts no throw + no reset line). The i18n mock was extended tointerpolate
{{name}}(previously returned the rawdefaultValue), needed to assertthe actual day/hour count renders.
.changeset/7371-ai-usage-indicator-weekly-reset.md— patch on@object-ui/app-shelland
@object-ui/i18n.Contract source
cloud PR #1852,
packages/objectos-runtime/src/ai-usage-endpoint-plugin.ts:Tests
All run from the repo root (per AGENTS.md's vitest-invocation-guard), against merge-base
20c04b232(rebased after #7366/#7367 landed touching i18n):pnpm --filter '@object-ui/app-shell^...' build— dependency closure, exit 0.pnpm exec vitest run packages/app-shell/src/layout/ packages/i18n/ --maxWorkers=2—91 test files / 1152 tests passed, 0 failed.
pnpm --filter @object-ui/app-shell type-check—tsc --noEmit && tsc -p tsconfig.test.json, exit 0.node scripts/check-i18n-call-site-keys.mjs— exit 0: "Every in-scope call-site keyresolves against the en pack (2959 keys)…".
node scripts/check-i18n-en-drift.mjs— exit 0: "0 en value(s) changed (6 key(s)added …)".
node scripts/check-i18n-dead-keys.mjs— report-only gate, exit 0; the two new basekeys do not appear in its dead-key report.
node scripts/check-changeset-presence.mjs— exit 0: "13 source file(s) of 2 releasedpackage(s) changed, and this change declares 1 changeset(s)".
node scripts/check-changeset-no-major.mjs/node scripts/check-control-bytes.mjs—exit 0.
Commit under test:
1b7793e10.Out of scope
None found specific to this file surface.
Generated by Claude Code