statusLine stdin missing `seven_day_sonnet` (and `seven_day_opus`) rate limit fields

Open 💬 2 comments Opened Jun 20, 2026 by Josef-Le

Summary

The rate_limits object piped to statusLine hooks only contains five_hour and seven_day, even though the internal schema and the /usage dialog both track seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, and extra_usage.

This makes it impossible for external status-bar tools to show model-specific quota usage, even though Claude Code already has the data.

Evidence from the binary

The Zod schema defined in the binary correctly includes all fields:

rate_limits: E.object({
  five_hour:             b2t().nullable().optional(),
  seven_day:             b2t().nullable().optional(),
  seven_day_oauth_apps:  b2t().nullable().optional(),
  seven_day_opus:        b2t().nullable().optional(),
  seven_day_sonnet:      b2t().nullable().optional(),
  extra_usage:           E.object({ ... }).nullable().optional()
})

But the actual object constructed for stdout only includes two of them:

R = {
  ...v.five_hour && { five_hour: { used_percentage: v.five_hour.utilization * 100, resets_at: v.five_hour.resets_at } },
  ...v.seven_day && { seven_day: { used_percentage: v.seven_day.utilization * 100, resets_at: v.seven_day.resets_at } }
  // seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, extra_usage are never written here
};

The /usage dialog (internal React component) reads seven_day_sonnet correctly from in-process state, but statusLine is an external process and only has what's in stdin.

Impact

Claude Max and Team subscribers have two separate 7-day quotas — one for all models combined and one for Sonnet specifically. The /usage dialog shows both. The statusLine hook can only show the all-models one, leaving Sonnet quota invisible to any external status bar.

Fix

Extend the stdin construction to include the model-specific fields when present, matching the same pattern already used for five_hour / seven_day:

R = {
  ...v.five_hour        && { five_hour:        { used_percentage: v.five_hour.utilization * 100,        resets_at: v.five_hour.resets_at } },
  ...v.seven_day        && { seven_day:        { used_percentage: v.seven_day.utilization * 100,        resets_at: v.seven_day.resets_at } },
  ...v.seven_day_sonnet && { seven_day_sonnet: { used_percentage: v.seven_day_sonnet.utilization * 100, resets_at: v.seven_day_sonnet.resets_at } },
  ...v.seven_day_opus   && { seven_day_opus:   { used_percentage: v.seven_day_opus.utilization * 100,   resets_at: v.seven_day_opus.resets_at } },
};

extra_usage (pay-as-you-go overage) would also be useful to expose so tools can show when a subscriber is burning overage credits.

Context

Discovered while debugging why a custom statusLine status bar (https://github.com/Josef-Le/claude-code-usage-bar) was unable to display the Sonnet-specific quota that is clearly visible in /usage. The data is there — it just doesn't reach the hook.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗