Skip to content

Commit b166645

Browse files
authored
fix: inherit terminal foreground color in quota table (#106)
- stop forcing model names to render in fixed white so light terminal themes stay readable - add a regression test to prevent hardcoded white ANSI text from returning - keep the change scoped to quota rendering to reduce risk for other CLI output
1 parent bceee9a commit b166645

2 files changed

Lines changed: 69 additions & 2 deletions

File tree

src/output/quota-table.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const B = '\x1b[1m';
88
const D = '\x1b[2m';
99
const MM_BLUE = '\x1b[38;2;43;82;255m';
1010
const MM_CYAN = '\x1b[38;2;6;184;212m';
11-
const WHITE = '\x1b[38;2;255;255;255m';
1211
const FG_GREEN = '\x1b[38;2;74;222;128m';
1312
const FG_YELLOW = '\x1b[38;2;250;204;21m';
1413
const FG_RED = '\x1b[38;2;248;113;113m';
@@ -127,7 +126,7 @@ export function renderQuotaTable(models: QuotaModelRemain[], config: Config): vo
127126
const line1VisLen = maxNameLen + 2 + 15 + 2 + barVisLen;
128127

129128
const line1 = useColor
130-
? `${B}${WHITE}${nameStr}${R} ${usageColors(usedPct)[0]}${usageFrac.padStart(15)}${R} ${bar}`
129+
? `${B}${nameStr}${R} ${usageColors(usedPct)[0]}${usageFrac.padStart(15)}${R} ${bar}`
131130
: `${nameStr} ${usageFrac.padStart(15)} ${renderBar(usedPct, false)}`;
132131
console.log(boxRow(line1, W, line1VisLen, useColor));
133132

test/output/quota-table.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { describe, it, expect } from 'bun:test';
2+
import { renderQuotaTable } from '../../src/output/quota-table';
3+
import type { Config } from '../../src/config/schema';
4+
import type { QuotaModelRemain } from '../../src/types/api';
5+
6+
const WHITE_ANSI = '\x1b[38;2;255;255;255m';
7+
8+
function createConfig(): Config {
9+
return {
10+
region: 'global',
11+
baseUrl: 'https://api.minimax.io',
12+
output: 'text',
13+
timeout: 10_000,
14+
verbose: false,
15+
quiet: false,
16+
noColor: false,
17+
yes: false,
18+
dryRun: false,
19+
nonInteractive: true,
20+
async: false,
21+
};
22+
}
23+
24+
function createModel(): QuotaModelRemain {
25+
return {
26+
model_name: 'MiniMax-M2',
27+
start_time: Date.UTC(2026, 3, 18, 0, 0, 0),
28+
end_time: Date.UTC(2026, 3, 18, 12, 0, 0),
29+
remains_time: 3 * 60 * 60 * 1000,
30+
current_interval_total_count: 1500,
31+
current_interval_usage_count: 80,
32+
current_weekly_total_count: 15000,
33+
current_weekly_usage_count: 666,
34+
weekly_start_time: Date.UTC(2026, 3, 12, 0, 0, 0),
35+
weekly_end_time: Date.UTC(2026, 3, 19, 0, 0, 0),
36+
weekly_remains_time: 3 * 60 * 60 * 1000,
37+
};
38+
}
39+
40+
describe('renderQuotaTable', () => {
41+
it('does not force model names to white in color mode', () => {
42+
const lines: string[] = [];
43+
const originalLog = console.log;
44+
const ttyDescriptor = Object.getOwnPropertyDescriptor(process.stdout, 'isTTY');
45+
46+
console.log = (message?: unknown) => {
47+
lines.push(String(message ?? ''));
48+
};
49+
Object.defineProperty(process.stdout, 'isTTY', {
50+
value: true,
51+
configurable: true,
52+
});
53+
54+
try {
55+
renderQuotaTable([createModel()], createConfig());
56+
} finally {
57+
console.log = originalLog;
58+
if (ttyDescriptor) {
59+
Object.defineProperty(process.stdout, 'isTTY', ttyDescriptor);
60+
}
61+
}
62+
63+
const output = lines.join('\n');
64+
65+
expect(output).toContain('MiniMax-M2');
66+
expect(output).not.toContain(WHITE_ANSI);
67+
});
68+
});

0 commit comments

Comments
 (0)