From ed405765166dceaad075ec8d44e599c473a208da Mon Sep 17 00:00:00 2001 From: liruifengv Date: Fri, 29 May 2026 13:42:34 +0800 Subject: [PATCH] fix(tui): show plan usage as percent used to match web console The `/status` and `/usage` "Plan usage" rows previously rendered the progress bar from the used ratio while labelling it "X% left", so the bar direction and the number disagreed. Display "X% used" instead, aligning the number with the bar, and move the reset hint to the right without parentheses to mirror the web console layout. --- .changeset/plan-usage-percent-used.md | 5 +++++ .../src/tui/components/messages/usage-panel.ts | 14 ++++++++------ .../tui/components/messages/status-panel.test.ts | 2 +- .../tui/components/messages/usage-panel.test.ts | 4 ++-- 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 .changeset/plan-usage-percent-used.md diff --git a/.changeset/plan-usage-percent-used.md b/.changeset/plan-usage-percent-used.md new file mode 100644 index 0000000000..57db3f142d --- /dev/null +++ b/.changeset/plan-usage-percent-used.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Improve the usage information display in the TUI. diff --git a/apps/kimi-code/src/tui/components/messages/usage-panel.ts b/apps/kimi-code/src/tui/components/messages/usage-panel.ts index 4db3d8c88b..0e4401a119 100644 --- a/apps/kimi-code/src/tui/components/messages/usage-panel.ts +++ b/apps/kimi-code/src/tui/components/messages/usage-panel.ts @@ -120,17 +120,19 @@ function buildManagedUsageSection( const rows: ManagedUsageRow[] = []; if (summary !== null) rows.push(summary); rows.push(...limits); + const usedRatio = (r: ManagedUsageRow): number => + r.limit > 0 ? Math.max(0, Math.min(r.used / r.limit, 1)) : 0; const labelWidth = Math.max(10, ...rows.map((r) => r.label.length)); + const pctWidth = Math.max(...rows.map((r) => `${Math.round(usedRatio(r) * 100)}% used`.length)); const out: string[] = [accent('Plan usage')]; for (const row of rows) { - const ratioUsed = row.limit > 0 ? row.used / row.limit : 0; - const leftRatio = 1 - Math.max(0, Math.min(ratioUsed, 1)); - const bar = renderProgressBar(Math.max(0, Math.min(ratioUsed, 1)), 20); - const pct = `${Math.round(leftRatio * 100)}% left`; + const ratioUsed = usedRatio(row); + const bar = renderProgressBar(ratioUsed, 20); + const pct = `${Math.round(ratioUsed * 100)}% used`; const barColoured = chalk.hex(severityHex(ratioSeverity(ratioUsed)))(bar); const label = row.label.padEnd(labelWidth, ' '); - const resetStr = row.resetHint ? muted(` (${row.resetHint})`) : ''; - out.push(` ${muted(label)} ${barColoured} ${value(pct)}${resetStr}`); + const resetStr = row.resetHint ? ` ${muted(row.resetHint)}` : ''; + out.push(` ${muted(label)} ${barColoured} ${value(pct.padEnd(pctWidth, ' '))}${resetStr}`); } return out; } diff --git a/apps/kimi-code/test/tui/components/messages/status-panel.test.ts b/apps/kimi-code/test/tui/components/messages/status-panel.test.ts index 0fec0bddf8..994fbf5253 100644 --- a/apps/kimi-code/test/tui/components/messages/status-panel.test.ts +++ b/apps/kimi-code/test/tui/components/messages/status-panel.test.ts @@ -64,7 +64,7 @@ describe('status panel report lines', () => { expect(output).toContain('25.0%'); expect(output).toContain('(3.0k / 12.0k)'); expect(output).toContain('Plan usage'); - expect(output).toContain('92% left'); + expect(output).toContain('8% used'); expect(output).not.toContain('Account'); expect(output).not.toContain('AGENTS.md'); expect(output).not.toContain('Runtime'); diff --git a/apps/kimi-code/test/tui/components/messages/usage-panel.test.ts b/apps/kimi-code/test/tui/components/messages/usage-panel.test.ts index e7d6c2c792..5e3883ca96 100644 --- a/apps/kimi-code/test/tui/components/messages/usage-panel.test.ts +++ b/apps/kimi-code/test/tui/components/messages/usage-panel.test.ts @@ -41,8 +41,8 @@ describe('UsagePanelComponent', () => { expect(lines).toContain('Context window'); expect(lines.join('\n')).toContain('25.0%'); expect(lines).toContain('Plan usage'); - expect(lines.join('\n')).toContain('80% left'); - expect(lines.join('\n')).toContain('(resets tomorrow)'); + expect(lines.join('\n')).toContain('20% used'); + expect(lines.join('\n')).toContain('resets tomorrow'); }); it('wraps preformatted usage lines in a bordered panel', () => {