-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Sidebar Account Profile with Rate Limit Popup #1381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Sidebar Account Profile with Rate Limit Popup #1381
Conversation
…nal sonnetWeeklyPercent and sonnetWeeklyResetTime fields
…or ClaudeUsageSnapshot - Create usage-store.ts following patterns from rate-limit-store.ts and claude-profile-store.ts - Add UsageState interface with usage, isLoading, and error state - Implement setUsage, setLoading, setError, and clearUsage actions - Add loadUsageData() async function for initial data load via IPC - Add subscribeToUsageUpdates() function for real-time updates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Created new AccountProfileIndicator component for sidebar with: - Minimalistic trigger button showing profile name and status indicator - Color-coded status dot based on usage thresholds (green/yellow/orange/red) - Detailed popup with session, weekly, and Sonnet usage progress bars - Integration with Zustand usage store for real-time updates - Proper loading, error, and no-data states - i18n translation keys for all user-facing text - Follows patterns from ClaudeCodeStatusBadge and UsageIndicator Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
….json for account profile section
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds a new AccountProfileIndicator UI component and supporting Zustand store for Claude usage snapshots, integrates it into the sidebar, adds a reusable UsageProgressBar and usage-color utilities, extends the usage type for Sonnet fields, and adds English and French localization keys. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as AccountProfileIndicator
participant Store as Usage Store (Zustand)
participant IPC as Renderer IPC
participant Main as Main Process
User->>UI: Mount component / open popover
activate UI
UI->>Store: loadUsageData()
activate Store
Store->>Store: setLoading(true)
Store->>IPC: requestUsageUpdate()
IPC->>Main: forward request
Main-->>IPC: return ClaudeUsageSnapshot
IPC-->>Store: deliver snapshot
Store->>Store: setUsage(snapshot), setLoading(false)
deactivate Store
UI->>Store: subscribeToUsageUpdates()
Store->>IPC: register onUsageUpdated listener
IPC->>Main: (listener registered)
Main->>IPC: emit usage update
IPC-->>Store: onUsageUpdated(newSnapshot)
Store->>Store: setUsage(newSnapshot)
Store->>UI: triggers re-render with updated usage
deactivate UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @AndyMik90, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new UI element in the sidebar that provides users with quick access to their Claude Code integration account status and detailed rate limit information. This enhancement aims to improve user awareness of their usage against various limits, including a new Sonnet-specific weekly limit, by presenting this data in an easily accessible and visually intuitive manner. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new AccountProfileIndicator component in the sidebar to display Claude account information and rate limit usage. It adds a new Zustand store (usage-store) for managing usage data, extends the ClaudeUsageSnapshot type, and includes new i18n strings. The implementation is solid, with good handling of loading and error states. My review includes suggestions to improve maintainability and robustness, such as refactoring duplicated logic, extracting a large component into a smaller one, using constants for magic numbers, and preventing race conditions in data loading. Overall, this is a great addition that enhances user visibility into their account status.
| function getUsageColor(percent: number): string { | ||
| if (percent >= 95) return 'bg-red-500'; | ||
| if (percent >= 91) return 'bg-orange-500'; | ||
| if (percent >= 71) return 'bg-yellow-500'; | ||
| return 'bg-green-500'; | ||
| } | ||
|
|
||
| /** | ||
| * Get the text color class for a usage percentage. | ||
| */ | ||
| function getUsageTextColor(percent: number): string { | ||
| if (percent >= 95) return 'text-red-500'; | ||
| if (percent >= 91) return 'text-orange-500'; | ||
| if (percent >= 71) return 'text-yellow-500'; | ||
| return 'text-green-500'; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getUsageColor and getUsageTextColor functions contain duplicated logic for determining colors based on usage percentage. This can be refactored by extracting the common logic into a helper function. This will improve maintainability and reduce redundancy, making it easier to update the thresholds and colors in one place.
function getUsageColorName(percent: number): string {
if (percent >= 95) return 'red-500';
if (percent >= 91) return 'orange-500';
if (percent >= 71) return 'yellow-500';
return 'green-500';
}
/**
* Get the color class for a usage percentage based on thresholds.
* Color thresholds: green (0-70), yellow (71-90), orange (91-94), red (95+)
*/
function getUsageColor(percent: number): string {
return `bg-${getUsageColorName(percent)}`;
}
/**
* Get the text color class for a usage percentage.
*/
function getUsageTextColor(percent: number): string {
return `text-${getUsageColorName(percent)}`;
}
| * - Detailed popup with session, weekly, and Sonnet usage | ||
| * - Color-coded progress bars based on usage thresholds | ||
| */ | ||
| export function AccountProfileIndicator({ className }: AccountProfileIndicatorProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AccountProfileIndicator component is quite large (over 200 lines) and handles both the trigger logic and the detailed popover content. To improve modularity and readability, consider extracting the content of the PopoverContent into a separate, more focused component (e.g., AccountProfilePopoverContent). This would simplify the AccountProfileIndicator to primarily manage the trigger and popover state.
| const displayName = usage?.profileName | ||
| ? usage.profileName.length > 20 | ||
| ? `${usage.profileName.substring(0, 17)}...` | ||
| : usage.profileName | ||
| : t('navigation:accountProfile.noProfile'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for truncating the displayName uses magic numbers (20 and 17). It's a best practice to define these as named constants at the top of the file or component. This improves code readability and makes it easier to understand the purpose of these values and modify them in the future.
// Truncate profile name if too long
const MAX_DISPLAY_NAME_LENGTH = 20;
const TRUNCATED_NAME_LENGTH = 17;
const displayName = usage?.profileName
? usage.profileName.length > MAX_DISPLAY_NAME_LENGTH
? `${usage.profileName.substring(0, TRUNCATED_NAME_LENGTH)}...`
: usage.profileName
: t('navigation:accountProfile.noProfile');
| const store = useUsageStore.getState(); | ||
| store.setLoading(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loadUsageData function could be called multiple times concurrently, leading to redundant network requests and potential race conditions with the isLoading state. To make it more robust, add a guard to prevent new data loading requests if one is already in progress.
| const store = useUsageStore.getState(); | |
| store.setLoading(true); | |
| const store = useUsageStore.getState(); | |
| if (store.isLoading) return; | |
| store.setLoading(true); |
AndyMik90
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 Auto Claude PR Review
Merge Verdict: 🟠 NEEDS REVISION
🟠 Needs revision - 1 issue(s) require attention.
Branch is out of date with base branch. Update branch first - if no conflicts arise, you can merge. If merge conflicts arise, resolve them and run follow-up review again. 1 issue(s) must be addressed (0 required, 1 recommended). 5 non-blocking suggestion(s) to consider.
Risk Assessment
| Factor | Level | Notes |
|---|---|---|
| Complexity | Medium | Based on lines changed |
| Security Impact | None | Based on security findings |
| Scope Coherence | Good | Based on structural review |
🚨 Blocking Issues (Must Fix)
- Branch Out of Date: PR branch is behind the base branch and needs to be updated
Findings Summary
- Medium: 1 issue(s)
- Low: 5 issue(s)
Generated by Auto Claude PR Review
Findings (6 selected of 6 total)
🟡 [df092b580fb4] [MEDIUM] [Potential] Inconsistent red threshold with existing UsageIndicator (95% vs 99%)
📁 apps/frontend/src/renderer/components/AccountProfileIndicator.tsx:19
AccountProfileIndicator.tsx uses 95% threshold for red color on ALL usage types, but existing UsageIndicator.tsx uses 99% for weekly usage (line 118). This causes visible UI inconsistency where 96% weekly usage shows red in the sidebar but orange in the header indicator. Users will see conflicting color signals for the same data.
Suggested fix:
Align thresholds between both components. Either update AccountProfileIndicator to use 99% for weekly (to match existing), or update UsageIndicator.tsx to use 95% consistently, then extract to a shared utility.
🔵 [19c5bc58da11] [LOW] [Potential] Color threshold logic duplicates existing UsageIndicator.tsx
📁 apps/frontend/src/renderer/components/AccountProfileIndicator.tsx:18
The getUsageColor() and getUsageTextColor() functions (lines 18-33) implement the same threshold logic (95, 91, 71) that already exists inline in UsageIndicator.tsx (lines 49-53, 91-94, 117-121). This duplication makes threshold changes error-prone (as evidenced by finding-1's inconsistency) and increases maintenance burden.
Suggested fix:
Extract color threshold logic to a shared utility like `src/renderer/lib/usage-colors.ts` with functions like `getUsageColorClass(percent, type: 'bg' | 'text')`. Both components should import from this shared location.
🔵 [70cf2c3938e2] [LOW] [Potential] setError does not clear stale usage data
📁 apps/frontend/src/renderer/stores/usage-store.ts:35
The setError action (lines 35-37) only sets the error without clearing the usage state. Meanwhile, setUsage (lines 24-29) properly clears error when setting usage. This asymmetry means when an API call fails after previously succeeding, both error AND stale usage data remain in the store. The UI could show the error message alongside outdated usage percentages.
Suggested fix:
Either have setError also clear usage: `set({ error, usage: null })`, or update AccountProfileIndicator.tsx UI to not display usage when there's an error: change `{usage && !isLoading && (` to `{usage && !isLoading && !error && (`
🔵 [88574f7e491c] [LOW] [Potential] Three nearly identical usage section JSX blocks
📁 apps/frontend/src/renderer/components/AccountProfileIndicator.tsx:198
The Session Usage (lines 198-218), Weekly Usage (lines 221-241), and Sonnet Weekly Usage (lines 244-266) sections are structurally identical, differing only in label translation key, percent value, and reset time. This creates ~60 lines of repetitive JSX that could be consolidated into a reusable UsageSection component.
Suggested fix:
Extract a UsageSection component that takes labelKey, percent, and resetTime props. Use it three times instead of repeating the JSX structure.
🔵 [15725805e477] [LOW] [Potential] UsageProgressBar duplicates pattern from UsageIndicator.tsx
📁 apps/frontend/src/renderer/components/AccountProfileIndicator.tsx:50
The UsageProgressBar component (lines 50-58) implements a progress bar pattern that already exists inline in UsageIndicator.tsx (lines 88-98 and 115-125). Both use identical structure: outer div with 'h-1.5 bg-muted rounded-full overflow-hidden' and inner div with dynamic width and color.
Suggested fix:
Extract UsageProgressBar to a shared UI component in src/renderer/components/ui/ that both AccountProfileIndicator and UsageIndicator can import.
🔵 [513f51e70939] [LOW] [Potential] Race condition in loadUsageData without concurrency guard
📁 apps/frontend/src/renderer/stores/usage-store.ts:51
The loadUsageData function has no guard against concurrent calls. If called multiple times rapidly, responses could arrive out of order causing stale data to overwrite fresh data. Currently only called on component mount (AccountProfileIndicator line 79), limiting practical impact, but the pattern is fragile if called from additional locations in the future.
Suggested fix:
Add a loading guard at the start: `if (store.isLoading) return;` or implement request cancellation with AbortController/request counter to ignore stale responses.
This review was generated by Auto Claude.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/frontend/src/renderer/components/AccountProfileIndicator.tsx`:
- Around line 180-184: The component AccountProfileIndicator renders a raw
user-visible error string; replace the direct {error} usage with an i18n
translation call (e.g., t('navigation.profileError', { error })) inside the
error block so the message is localized, and add the corresponding key
"profileError": "Error: {{error}}" (and French equivalent) to both en/fr
navigation.json files; ensure you import/use the same translation hook used
elsewhere (e.g., useTranslation or t) and keep the surrounding markup
(AlertTriangle, classes, condition) unchanged.
♻️ Duplicate comments (1)
apps/frontend/src/renderer/stores/usage-store.ts (1)
35-43: Clear stale usage when setting an error.
Keeping prior usage while settingerrorallows stale data to render alongside the error state.✅ Suggested fix
- setError: (error: string | null) => { - set({ error }); - }, + setError: (error: string | null) => { + set({ error, usage: null }); + },
| {error && !isLoading && ( | ||
| <div className="text-xs p-2 bg-destructive/10 text-destructive rounded-md flex items-center gap-2"> | ||
| <AlertTriangle className="h-3 w-3 shrink-0" /> | ||
| <span>{error}</span> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Localize the dynamic error message.
The raw error string is user-visible and bypasses i18n; wrap it in a translation key with interpolation and add the key to both en/fr navigation.json.
✅ Suggested fix
- <span>{error}</span>
+ <span>{t('navigation:accountProfile.errorWithDetail', { error })}</span>🤖 Prompt for AI Agents
In `@apps/frontend/src/renderer/components/AccountProfileIndicator.tsx` around
lines 180 - 184, The component AccountProfileIndicator renders a raw
user-visible error string; replace the direct {error} usage with an i18n
translation call (e.g., t('navigation.profileError', { error })) inside the
error block so the message is localized, and add the corresponding key
"profileError": "Error: {{error}}" (and French equivalent) to both en/fr
navigation.json files; ensure you import/use the same translation hook used
elsewhere (e.g., useTranslation or t) and keep the surrounding markup
(AlertTriangle, classes, condition) unchanged.
…plication - Fix inconsistent red threshold (95% vs 99%) between UsageIndicator and AccountProfileIndicator by creating shared usage-colors.ts utility - Extract reusable UsageProgressBar component to ui/ folder - Add UsageSection component to reduce repetitive JSX (~60 lines) - Fix setError to clear stale usage data preventing outdated display - Add concurrency guard to loadUsageData preventing race conditions - Add !error check to usage display condition to hide usage during errors Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace 6 hardcoded English strings in UsageIndicator.tsx with i18n keys - Add useTranslation hook for navigation namespace - Add missing translation keys (activeAccount, usageStatusAriaLabel) to both English and French navigation.json - Export UsageProgressBar from ui/index.ts for consistency Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8ae09d7 to
dfebe67
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/frontend/src/renderer/components/ui/usage-progress-bar.tsx`:
- Around line 13-21: The UsageProgressBar component is missing ARIA attributes;
update the inner and/or outer element in UsageProgressBar to include
role="progressbar" and set aria-valuemin="0", aria-valuemax="100" and
aria-valuenow={Math.min(Math.round(percent), 100)} (or provide aria-valuetext
for a custom label) so screen readers can expose the percent; keep the visual
width logic (style width: `${Math.min(percent,100)}%`) and ensure
getUsageBgColor(percent) remains used for color so accessibility does not change
appearance.
♻️ Duplicate comments (3)
apps/frontend/src/renderer/stores/usage-store.ts (1)
65-69: Handle the case when API returns unsuccessful without an error message.When
result.successisfalsebutresult.erroris falsy, neithersetUsagenorsetErroris called. The loading state clears, leavingusageasnulland displaying "No data available" instead of an appropriate error message.Proposed fix
if (result.success && result.data) { store.setUsage(result.data); } else if (result.error) { store.setError(result.error); + } else { + store.setError('Failed to load usage data'); }apps/frontend/src/renderer/components/AccountProfileIndicator.tsx (2)
110-115: Extract magic numbers to named constants.The truncation logic uses magic numbers (20 and 17). Define these as named constants for improved readability and maintainability.
Proposed refactor
+const MAX_DISPLAY_NAME_LENGTH = 20; +const TRUNCATED_NAME_SUFFIX_LENGTH = 17; + export function AccountProfileIndicator({ className }: AccountProfileIndicatorProps) { // ... // Truncate profile name if too long const displayName = usage?.profileName - ? usage.profileName.length > 20 - ? `${usage.profileName.substring(0, 17)}...` + ? usage.profileName.length > MAX_DISPLAY_NAME_LENGTH + ? `${usage.profileName.substring(0, TRUNCATED_NAME_SUFFIX_LENGTH)}...` : usage.profileName : t('navigation:accountProfile.noProfile');
182-188: Localize the dynamic error message.The raw
errorstring is displayed directly to users, bypassing i18n. Use interpolation to wrap the error message in a translation key. As per coding guidelines, all user-facing text must use i18n translation keys.Proposed fix
{/* Error state */} {error && !isLoading && ( <div className="text-xs p-2 bg-destructive/10 text-destructive rounded-md flex items-center gap-2"> <AlertTriangle className="h-3 w-3 shrink-0" /> - <span>{error}</span> + <span>{t('navigation:accountProfile.errorWithDetail', { error })}</span> </div> )}Add the corresponding key to both locale files:
en/navigation.json:
"errorWithDetail": "Error: {{error}}"fr/navigation.json:
"errorWithDetail": "Erreur: {{error}}"
| export function UsageProgressBar({ percent, className }: UsageProgressBarProps) { | ||
| return ( | ||
| <div className={cn('mt-1.5 h-1.5 bg-muted rounded-full overflow-hidden', className)}> | ||
| <div | ||
| className={cn('h-full transition-all', getUsageBgColor(percent))} | ||
| style={{ width: `${Math.min(percent, 100)}%` }} | ||
| /> | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider adding ARIA attributes for accessibility.
The progress bar is functional but lacks accessibility attributes. Screen readers won't convey the progress information.
♻️ Suggested improvement for accessibility
export function UsageProgressBar({ percent, className }: UsageProgressBarProps) {
+ const clampedPercent = Math.min(Math.max(percent, 0), 100);
return (
- <div className={cn('mt-1.5 h-1.5 bg-muted rounded-full overflow-hidden', className)}>
+ <div
+ role="progressbar"
+ aria-valuenow={Math.round(clampedPercent)}
+ aria-valuemin={0}
+ aria-valuemax={100}
+ className={cn('mt-1.5 h-1.5 bg-muted rounded-full overflow-hidden', className)}
+ >
<div
className={cn('h-full transition-all', getUsageBgColor(percent))}
- style={{ width: `${Math.min(percent, 100)}%` }}
+ style={{ width: `${clampedPercent}%` }}
/>
</div>
);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function UsageProgressBar({ percent, className }: UsageProgressBarProps) { | |
| return ( | |
| <div className={cn('mt-1.5 h-1.5 bg-muted rounded-full overflow-hidden', className)}> | |
| <div | |
| className={cn('h-full transition-all', getUsageBgColor(percent))} | |
| style={{ width: `${Math.min(percent, 100)}%` }} | |
| /> | |
| </div> | |
| ); | |
| export function UsageProgressBar({ percent, className }: UsageProgressBarProps) { | |
| const clampedPercent = Math.min(Math.max(percent, 0), 100); | |
| return ( | |
| <div | |
| role="progressbar" | |
| aria-valuenow={Math.round(clampedPercent)} | |
| aria-valuemin={0} | |
| aria-valuemax={100} | |
| className={cn('mt-1.5 h-1.5 bg-muted rounded-full overflow-hidden', className)} | |
| > | |
| <div | |
| className={cn('h-full transition-all', getUsageBgColor(percent))} | |
| style={{ width: `${clampedPercent}%` }} | |
| /> | |
| </div> | |
| ); | |
| } |
🤖 Prompt for AI Agents
In `@apps/frontend/src/renderer/components/ui/usage-progress-bar.tsx` around lines
13 - 21, The UsageProgressBar component is missing ARIA attributes; update the
inner and/or outer element in UsageProgressBar to include role="progressbar" and
set aria-valuemin="0", aria-valuemax="100" and
aria-valuenow={Math.min(Math.round(percent), 100)} (or provide aria-valuetext
for a custom label) so screen readers can expose the percent; keep the visual
width logic (style width: `${Math.min(percent,100)}%`) and ensure
getUsageBgColor(percent) remains used for color so accessibility does not change
appearance.
…error-type-authentication
…error-type-authentication
There was a problem hiding this comment.
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 and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| style={{ width: `${Math.min(usage.weeklyPercent, 100)}%` }} | ||
| /> | ||
| </div> | ||
| <UsageProgressBar percent={usage.weeklyPercent} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weekly progress bar red threshold changed from 99% to 95%
Medium Severity
The refactoring to use the shared UsageProgressBar component inadvertently changed the weekly usage red threshold from 99% to 95%. The original code intentionally used different thresholds - session at 95% and weekly at 99% - but the new shared component uses a unified 95% threshold. Users will now see the weekly progress bar turn red 4% earlier than before, which changes the existing user experience.
67a743f to
e83e445
Compare
Add a minimalistic account profile indicator to the sidebar that shows the active Claude Code integration account. When the user hovers over this indicator, a popup should display detailed rate limit information including session usage, weekly usage (all models), and weekly usage (Sonnet only). This feature integrates with the existing usage monitoring system and requires extending it to support the additional Sonnet-only usage metric.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.