fix(cliproxy): fall back from invalid Codex feature labels

This commit is contained in:
Tam Nhu Tran
2026-05-30 15:38:50 -04:00
parent 457412277b
commit a0870aa404
3 changed files with 40 additions and 17 deletions
+7 -3
View File
@@ -11,8 +11,8 @@ const TERMINAL_CONTROL_CHARS_REGEX = /[\u0000-\u001f\u007f-\u009f]/g;
* labels must be constrained to safe, printable strings before they reach the
* terminal.
*/
export function sanitizeCodexFeatureLabel(value: unknown): string {
if (typeof value !== 'string') return CODEX_FEATURE_LABEL_FALLBACK;
export function sanitizeCodexFeatureLabelOrNull(value: unknown): string | null {
if (typeof value !== 'string') return null;
const sanitized = value
.replace(TERMINAL_ESCAPE_SEQUENCE_REGEX, '')
@@ -21,5 +21,9 @@ export function sanitizeCodexFeatureLabel(value: unknown): string {
.slice(0, CODEX_FEATURE_LABEL_MAX_LENGTH)
.trimEnd();
return sanitized.length > 0 ? sanitized : CODEX_FEATURE_LABEL_FALLBACK;
return sanitized.length > 0 ? sanitized : null;
}
export function sanitizeCodexFeatureLabel(value: unknown): string {
return sanitizeCodexFeatureLabelOrNull(value) ?? CODEX_FEATURE_LABEL_FALLBACK;
}
+11 -5
View File
@@ -18,7 +18,10 @@ import {
} from '../../cliproxy/accounts/account-manager';
import { fetchAllProviderQuotas } from '../../cliproxy/quota/quota-fetcher';
import { fetchAllCodexQuotas } from '../../cliproxy/quota/quota-fetcher-codex';
import { sanitizeCodexFeatureLabel } from '../../cliproxy/quota/quota-label-sanitizer';
import {
sanitizeCodexFeatureLabel,
sanitizeCodexFeatureLabelOrNull,
} from '../../cliproxy/quota/quota-label-sanitizer';
import { fetchAllClaudeQuotas } from '../../cliproxy/quota/quota-fetcher-claude';
import { pickMostRestrictiveClaudeWeeklyWindow } from '../../cliproxy/quota/quota-fetcher-claude-normalizer';
import { fetchAllGeminiCliQuotas } from '../../cliproxy/quota/quota-fetcher-gemini-cli';
@@ -280,9 +283,12 @@ function inferCodeReviewCadence(
* Strip a leading "GPT-X.Y-Codex-" prefix from a feature label and turn the
* remainder into a Codex-prefixed display name. Other labels pass through unchanged.
*/
function prettifyCodexFeatureLabel(featureLabel: unknown): string {
const trimmed = sanitizeCodexFeatureLabel(featureLabel);
if (!trimmed) return 'Additional';
function prettifyCodexFeatureLabel(featureLabel: unknown, fallbackLabel?: unknown): string {
const trimmed =
sanitizeCodexFeatureLabelOrNull(featureLabel) ??
(fallbackLabel === undefined
? sanitizeCodexFeatureLabel(featureLabel)
: sanitizeCodexFeatureLabel(fallbackLabel));
const stripped = trimmed.replace(/^GPT-[\d.]+-Codex-/i, '');
if (stripped !== trimmed && stripped.length > 0) {
return `Codex ${stripped}`;
@@ -303,7 +309,7 @@ function getCodexWindowDisplayLabel(
}
if (window.category === 'additional') {
const pretty = prettifyCodexFeatureLabel(window.featureLabel ?? window.label);
const pretty = prettifyCodexFeatureLabel(window.featureLabel, window.label);
if (window.cadence === '5h') return `${pretty} (5h)`;
if (window.cadence === 'weekly') return `${pretty} (weekly)`;
return pretty;
@@ -86,18 +86,31 @@ describe('cliproxy quota subcommand failure formatting', () => {
});
describe('cliproxy quota subcommand Codex label formatting', () => {
it('falls back for non-string cached Codex feature labels', async () => {
it('falls back to the cached window label for invalid Codex feature labels', async () => {
const { getCodexWindowDisplayLabel } = await loadQuotaCommandTestExports();
const label = getCodexWindowDisplayLabel({
label: 'ignored',
resetAfterSeconds: 3600,
category: 'additional',
cadence: '5h',
featureLabel: { unexpected: true },
} as never);
const cases = [
{ featureLabel: '', cadence: '5h', expected: 'Codex Spark (5h)' },
{ featureLabel: ' ', cadence: 'weekly', expected: 'Codex Spark (weekly)' },
{
featureLabel: '\u001b[2J\u001b]52;c;payload\u0007',
cadence: '5h',
expected: 'Codex Spark (5h)',
},
{ featureLabel: { unexpected: true }, cadence: '5h', expected: 'Codex Spark (5h)' },
] as const;
expect(label).toBe('Additional (5h)');
for (const { featureLabel, cadence, expected } of cases) {
const label = getCodexWindowDisplayLabel({
label: 'GPT-5.3-Codex-Spark',
resetAfterSeconds: 3600,
category: 'additional',
cadence,
featureLabel,
} as never);
expect(label).toBe(expected);
}
});
it('removes terminal control characters from cached Codex feature labels', async () => {