Skip to content

feat: persist 5h and weekly plan quota in TUI footer and web sidebar#1827

Open
hawkparrot wants to merge 1 commit into
MoonshotAI:mainfrom
hawkparrot:feat/persistent-plan-quota
Open

feat: persist 5h and weekly plan quota in TUI footer and web sidebar#1827
hawkparrot wants to merge 1 commit into
MoonshotAI:mainfrom
hawkparrot:feat/persistent-plan-quota

Conversation

@hawkparrot

Copy link
Copy Markdown

What

The managed GET /usages endpoint already returns both rolling windows (the weekly summary and the 5h window in limits[]), but they were only reachable behind /usage and /status. This surfaces them persistently in both UIs.

TUI

  • Footer line 2 now shows a compact 5h: X% 1w: Y% readout next to the context meter, each window coloured by its own severity (green/yellow/red).
  • The report is cached in AppState, fetched fire-and-forget on session sync (refreshManagedUsage), and refreshed whenever /usage or /status runs.

Web

  • New GET /api/v1/usages route in kap-server, backed by IOAuthToolkit.getManagedUsage (interface now declares it).
  • New QuotaCard component pinned above the sidebar session list: per-window progress bars, reset hints, and a manual Refresh button. Fetches once on mount.
  • getManagedUsage() added to the web API client + wire/App types; EN/ZH i18n strings.

Both UIs hide the quota entirely for non-managed providers / signed-out users and degrade to an error hint instead of failing.

Testing

  • pnpm typecheck clean across all packages.
  • Footer/usage-panel, agent-core-v2 auth, kap-server (660), oauth managed-usage tests all pass; API-surface snapshot updated for the new route.
  • Verified live against a managed account: 5h/weekly percentages render in both the TUI footer and the web sidebar.

Includes a changeset (@moonshot-ai/kimi-code minor).

The managed /usages endpoint already returns both rolling windows, but they
were only visible behind /usage and /status. Surface them persistently:

- TUI: footer line 2 now shows a compact '5h: X% 1w: Y%' readout next to the
  context meter, cached in appState, fetched on session sync and refreshed by
  /usage and /status.
- Web: new GET /api/v1/usages route (IOAuthToolkit.getManagedUsage), a Plan
  usage card pinned above the sidebar session list with per-window progress
  bars and a manual refresh.
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bc7e247

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc7e247799

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

goal: goalResult.goal,
});
this.syncAdditionalDirs(session);
void this.refreshManagedUsage();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh quota when the active provider changes

Calling refreshManagedUsage() only from session runtime sync misses provider changes that update appState.model directly, such as /model switching through performModelSwitch after session.setModel. In that scenario, switching from managed:kimi-code to a non-managed provider leaves the previous managedUsage in state and the footer keeps showing the old 5h/1w quota; switching the other way does not fetch quota until some later session sync or command happens. Trigger this refresh/clear path whenever the model/provider changes, not just during syncRuntimeState.

Useful? React with 👍 / 👎.

out.push(...r.limits);
return out;
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Show API-level quota errors in the card

When /api/v1/usages returns a successful envelope with { kind: 'error' } (for example, the managed usage endpoint times out or returns an HTTP error), refresh() resolves normally and sets failed to false; rows is empty, so this visible computed becomes false and the template never reaches the existing error/retry branch. Include result.value?.kind === 'error' in the visibility condition or map that result to the error state so managed users can see and retry quota fetch failures.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant