Skip to content

Commit 9aa4880

Browse files
committed
feat(cli): invert quota language to percent used
1 parent 81cd256 commit 9aa4880

File tree

10 files changed

+62
-43
lines changed

10 files changed

+62
-43
lines changed

packages/cli/src/ui/components/Footer.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ describe('<Footer />', () => {
182182
},
183183
);
184184
await waitUntilReady();
185-
expect(lastFrame()).toContain('15%');
185+
expect(lastFrame()).toContain('85%');
186186
expect(lastFrame()).toMatchSnapshot();
187187
unmount();
188188
});

packages/cli/src/ui/components/QuotaDisplay.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('QuotaDisplay', () => {
3636
unmount();
3737
});
3838

39-
it('should not render when usage > 20%', async () => {
39+
it('should not render when usage < 80%', async () => {
4040
const { lastFrame, waitUntilReady, unmount } = render(
4141
<QuotaDisplay remaining={85} limit={100} />,
4242
);
@@ -45,7 +45,7 @@ describe('QuotaDisplay', () => {
4545
unmount();
4646
});
4747

48-
it('should render yellow when usage < 20%', async () => {
48+
it('should render warning when used >= 80%', async () => {
4949
const { lastFrame, waitUntilReady, unmount } = render(
5050
<QuotaDisplay remaining={15} limit={100} />,
5151
);
@@ -54,7 +54,7 @@ describe('QuotaDisplay', () => {
5454
unmount();
5555
});
5656

57-
it('should render red when usage < 5%', async () => {
57+
it('should render critical when used >= 95%', async () => {
5858
const { lastFrame, waitUntilReady, unmount } = render(
5959
<QuotaDisplay remaining={4} limit={100} />,
6060
);

packages/cli/src/ui/components/QuotaDisplay.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import type React from 'react';
88
import { Text } from 'ink';
99
import {
10-
getStatusColor,
11-
QUOTA_THRESHOLD_HIGH,
12-
QUOTA_THRESHOLD_MEDIUM,
10+
getUsedStatusColor,
11+
QUOTA_USED_WARNING_THRESHOLD,
12+
QUOTA_USED_CRITICAL_THRESHOLD,
1313
} from '../utils/displayUtils.js';
1414
import { formatResetTime } from '../utils/formatters.js';
1515

@@ -30,15 +30,15 @@ export const QuotaDisplay: React.FC<QuotaDisplayProps> = ({
3030
return null;
3131
}
3232

33-
const percentage = (remaining / limit) * 100;
33+
const usedPercentage = 100 - (remaining / limit) * 100;
3434

35-
if (percentage > QUOTA_THRESHOLD_HIGH) {
35+
if (usedPercentage < QUOTA_USED_WARNING_THRESHOLD) {
3636
return null;
3737
}
3838

39-
const color = getStatusColor(percentage, {
40-
green: QUOTA_THRESHOLD_HIGH,
41-
yellow: QUOTA_THRESHOLD_MEDIUM,
39+
const color = getUsedStatusColor(usedPercentage, {
40+
warning: QUOTA_USED_WARNING_THRESHOLD,
41+
critical: QUOTA_USED_CRITICAL_THRESHOLD,
4242
});
4343

4444
const resetInfo =
@@ -57,8 +57,8 @@ export const QuotaDisplay: React.FC<QuotaDisplayProps> = ({
5757
return (
5858
<Text color={color}>
5959
{terse
60-
? `${percentage.toFixed(0)}%`
61-
: `/stats ${percentage.toFixed(0)}% usage remaining${resetInfo}`}
60+
? `${usedPercentage.toFixed(0)}%`
61+
: `/stats ${usedPercentage.toFixed(0)}% used${resetInfo}`}
6262
</Text>
6363
);
6464
};

packages/cli/src/ui/components/QuotaStatsInfo.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { Box, Text } from 'ink';
99
import { theme } from '../semantic-colors.js';
1010
import { formatResetTime } from '../utils/formatters.js';
1111
import {
12-
getStatusColor,
13-
QUOTA_THRESHOLD_HIGH,
14-
QUOTA_THRESHOLD_MEDIUM,
12+
getUsedStatusColor,
13+
QUOTA_USED_WARNING_THRESHOLD,
14+
QUOTA_USED_CRITICAL_THRESHOLD,
1515
} from '../utils/displayUtils.js';
1616

1717
interface QuotaStatsInfoProps {
@@ -31,18 +31,18 @@ export const QuotaStatsInfo: React.FC<QuotaStatsInfoProps> = ({
3131
return null;
3232
}
3333

34-
const percentage = (remaining / limit) * 100;
35-
const color = getStatusColor(percentage, {
36-
green: QUOTA_THRESHOLD_HIGH,
37-
yellow: QUOTA_THRESHOLD_MEDIUM,
34+
const usedPercentage = 100 - (remaining / limit) * 100;
35+
const color = getUsedStatusColor(usedPercentage, {
36+
warning: QUOTA_USED_WARNING_THRESHOLD,
37+
critical: QUOTA_USED_CRITICAL_THRESHOLD,
3838
});
3939

4040
return (
4141
<Box flexDirection="column" marginTop={0} marginBottom={0}>
4242
<Text color={color}>
4343
{remaining === 0
4444
? `Limit reached`
45-
: `${percentage.toFixed(0)}% usage remaining`}
45+
: `${usedPercentage.toFixed(0)}% used`}
4646
{resetTime && `, ${formatResetTime(resetTime)}`}
4747
</Text>
4848
{showDetails && (

packages/cli/src/ui/components/StatsDisplay.test.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ describe('<StatsDisplay />', () => {
465465
await waitUntilReady();
466466
const output = lastFrame();
467467

468-
expect(output).toContain('Usage remaining');
469-
expect(output).toContain('75.0%');
468+
expect(output).toContain('Usage');
469+
expect(output).toContain('25.0% used');
470470
expect(output).toContain('resets in 1h 30m');
471471
expect(output).toMatchSnapshot();
472472

@@ -521,8 +521,8 @@ describe('<StatsDisplay />', () => {
521521
await waitUntilReady();
522522
const output = lastFrame();
523523

524-
// (10 + 700) / (100 + 1000) = 710 / 1100 = 64.5%
525-
expect(output).toContain('65% usage remaining');
524+
// (1 - 710/1100) * 100 = 35.5%
525+
expect(output).toContain('35% used');
526526
expect(output).toContain('Usage limit: 1,100');
527527
expect(output).toMatchSnapshot();
528528

@@ -571,7 +571,7 @@ describe('<StatsDisplay />', () => {
571571

572572
expect(output).toContain('gemini-2.5-flash');
573573
expect(output).toContain('-'); // for requests
574-
expect(output).toContain('50.0%');
574+
expect(output).toContain('50.0% used');
575575
expect(output).toContain('resets in 2h');
576576
expect(output).toMatchSnapshot();
577577

packages/cli/src/ui/components/StatsDisplay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ const ModelUsageTable: React.FC<{
273273
alignItems="flex-end"
274274
>
275275
<Text bold color={theme.text.primary}>
276-
Usage remaining
276+
Usage
277277
</Text>
278278
</Box>
279279
)}
@@ -361,7 +361,7 @@ const ModelUsageTable: React.FC<{
361361
row.bucket.remainingFraction != null &&
362362
row.bucket.resetTime && (
363363
<Text color={theme.text.secondary} wrap="truncate-end">
364-
{(row.bucket.remainingFraction * 100).toFixed(1)}%{' '}
364+
{((1 - row.bucket.remainingFraction) * 100).toFixed(1)}% used{' '}
365365
{formatResetTime(row.bucket.resetTime)}
366366
</Text>
367367
)}

packages/cli/src/ui/components/__snapshots__/Footer.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ exports[`<Footer /> > displays "Limit reached" message when remaining is 0 1`] =
66
`;
77

88
exports[`<Footer /> > displays the usage indicator when usage is low 1`] = `
9-
" ...directories/to/make/it/long no sandbox (see /docs) /model gemini-pro 15%
9+
" ...directories/to/make/it/long no sandbox (see /docs) /model gemini-pro 85%
1010
"
1111
`;
1212

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`QuotaDisplay > should NOT render reset time when terse is true 1`] = `
4-
"15%
4+
"85%
55
"
66
`;
77

8-
exports[`QuotaDisplay > should render red when usage < 5% 1`] = `
9-
"/stats 4% usage remaining
8+
exports[`QuotaDisplay > should render critical when used >= 95% 1`] = `
9+
"/stats 96% used
1010
"
1111
`;
1212

@@ -15,12 +15,12 @@ exports[`QuotaDisplay > should render terse limit reached message 1`] = `
1515
"
1616
`;
1717

18-
exports[`QuotaDisplay > should render with reset time when provided 1`] = `
19-
"/stats 15% usage remaining, resets in 1h
18+
exports[`QuotaDisplay > should render warning when used >= 80% 1`] = `
19+
"/stats 85% used
2020
"
2121
`;
2222

23-
exports[`QuotaDisplay > should render yellow when usage < 20% 1`] = `
24-
"/stats 15% usage remaining
23+
exports[`QuotaDisplay > should render with reset time when provided 1`] = `
24+
"/stats 85% used, resets in 1h
2525
"
2626
`;

packages/cli/src/ui/components/__snapshots__/StatsDisplay.test.tsx.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ exports[`<StatsDisplay /> > Quota Display > renders pooled quota information for
163163
│ » Tool Time: 0s (0.0%) │
164164
│ │
165165
│ auto Usage │
166-
65% usage remaining
166+
35% used
167167
│ Usage limit: 1,100 │
168168
│ Usage limits span all sessions and reset daily. │
169169
│ For a full token breakdown, run \`/stats model\`. │
170170
│ │
171-
│ Model Reqs Usage remaining
171+
│ Model Reqs Usage
172172
│ ──────────────────────────────────────────────────────────── │
173173
│ gemini-2.5-pro - │
174174
│ gemini-2.5-flash - │
@@ -194,9 +194,9 @@ exports[`<StatsDisplay /> > Quota Display > renders quota information for unused
194194
│ » Tool Time: 0s (0.0%) │
195195
│ │
196196
│ Model Usage │
197-
│ Model Reqs Usage remaining
197+
│ Model Reqs Usage
198198
│ ──────────────────────────────────────────────────────────── │
199-
│ gemini-2.5-flash - 50.0% resets in 2h │
199+
│ gemini-2.5-flash - 50.0% used resets in 2h │
200200
│ │
201201
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
202202
"
@@ -219,9 +219,9 @@ exports[`<StatsDisplay /> > Quota Display > renders quota information when quota
219219
│ » Tool Time: 0s (0.0%) │
220220
│ │
221221
│ Model Usage │
222-
│ Model Reqs Usage remaining
222+
│ Model Reqs Usage
223223
│ ──────────────────────────────────────────────────────────── │
224-
│ gemini-2.5-pro 1 75.0% resets in 1h 30m │
224+
│ gemini-2.5-pro 1 25.0% used resets in 1h 30m │
225225
│ │
226226
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
227227
"

packages/cli/src/ui/utils/displayUtils.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export const CACHE_EFFICIENCY_MEDIUM = 15;
1919
export const QUOTA_THRESHOLD_HIGH = 20;
2020
export const QUOTA_THRESHOLD_MEDIUM = 5;
2121

22+
export const QUOTA_USED_WARNING_THRESHOLD = 80;
23+
export const QUOTA_USED_CRITICAL_THRESHOLD = 95;
24+
2225
// --- Color Logic ---
2326
export const getStatusColor = (
2427
value: number,
@@ -36,3 +39,19 @@ export const getStatusColor = (
3639
}
3740
return options.defaultColor ?? theme.status.error;
3841
};
42+
43+
/**
44+
* Gets the status color based on "used" percentage (where higher is worse).
45+
*/
46+
export const getUsedStatusColor = (
47+
usedPercentage: number,
48+
thresholds: { warning: number; critical: number },
49+
) => {
50+
if (usedPercentage >= thresholds.critical) {
51+
return theme.status.error;
52+
}
53+
if (usedPercentage >= thresholds.warning) {
54+
return theme.status.warning;
55+
}
56+
return theme.status.success;
57+
};

0 commit comments

Comments
 (0)