From 419c7dd61b50910ef202cdc62949ac199d30b035 Mon Sep 17 00:00:00 2001 From: dabaotongxue <297390763@qq.com> Date: Sat, 18 Apr 2026 11:37:48 +0800 Subject: [PATCH] fix: inherit terminal foreground color in quota table - 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 --- src/output/quota-table.ts | 3 +- test/output/quota-table.test.ts | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 test/output/quota-table.test.ts diff --git a/src/output/quota-table.ts b/src/output/quota-table.ts index 5b5fbe4..d85f575 100644 --- a/src/output/quota-table.ts +++ b/src/output/quota-table.ts @@ -8,7 +8,6 @@ const B = '\x1b[1m'; const D = '\x1b[2m'; const MM_BLUE = '\x1b[38;2;43;82;255m'; const MM_CYAN = '\x1b[38;2;6;184;212m'; -const WHITE = '\x1b[38;2;255;255;255m'; const FG_GREEN = '\x1b[38;2;74;222;128m'; const FG_YELLOW = '\x1b[38;2;250;204;21m'; const FG_RED = '\x1b[38;2;248;113;113m'; @@ -127,7 +126,7 @@ export function renderQuotaTable(models: QuotaModelRemain[], config: Config): vo const line1VisLen = maxNameLen + 2 + 15 + 2 + barVisLen; const line1 = useColor - ? `${B}${WHITE}${nameStr}${R} ${usageColors(usedPct)[0]}${usageFrac.padStart(15)}${R} ${bar}` + ? `${B}${nameStr}${R} ${usageColors(usedPct)[0]}${usageFrac.padStart(15)}${R} ${bar}` : `${nameStr} ${usageFrac.padStart(15)} ${renderBar(usedPct, false)}`; console.log(boxRow(line1, W, line1VisLen, useColor)); diff --git a/test/output/quota-table.test.ts b/test/output/quota-table.test.ts new file mode 100644 index 0000000..36f0b8d --- /dev/null +++ b/test/output/quota-table.test.ts @@ -0,0 +1,68 @@ +import { describe, it, expect } from 'bun:test'; +import { renderQuotaTable } from '../../src/output/quota-table'; +import type { Config } from '../../src/config/schema'; +import type { QuotaModelRemain } from '../../src/types/api'; + +const WHITE_ANSI = '\x1b[38;2;255;255;255m'; + +function createConfig(): Config { + return { + region: 'global', + baseUrl: 'https://api.minimax.io', + output: 'text', + timeout: 10_000, + verbose: false, + quiet: false, + noColor: false, + yes: false, + dryRun: false, + nonInteractive: true, + async: false, + }; +} + +function createModel(): QuotaModelRemain { + return { + model_name: 'MiniMax-M2', + start_time: Date.UTC(2026, 3, 18, 0, 0, 0), + end_time: Date.UTC(2026, 3, 18, 12, 0, 0), + remains_time: 3 * 60 * 60 * 1000, + current_interval_total_count: 1500, + current_interval_usage_count: 80, + current_weekly_total_count: 15000, + current_weekly_usage_count: 666, + weekly_start_time: Date.UTC(2026, 3, 12, 0, 0, 0), + weekly_end_time: Date.UTC(2026, 3, 19, 0, 0, 0), + weekly_remains_time: 3 * 60 * 60 * 1000, + }; +} + +describe('renderQuotaTable', () => { + it('does not force model names to white in color mode', () => { + const lines: string[] = []; + const originalLog = console.log; + const ttyDescriptor = Object.getOwnPropertyDescriptor(process.stdout, 'isTTY'); + + console.log = (message?: unknown) => { + lines.push(String(message ?? '')); + }; + Object.defineProperty(process.stdout, 'isTTY', { + value: true, + configurable: true, + }); + + try { + renderQuotaTable([createModel()], createConfig()); + } finally { + console.log = originalLog; + if (ttyDescriptor) { + Object.defineProperty(process.stdout, 'isTTY', ttyDescriptor); + } + } + + const output = lines.join('\n'); + + expect(output).toContain('MiniMax-M2'); + expect(output).not.toContain(WHITE_ANSI); + }); +});