mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 12:15:57 +00:00
fix: persist codex target selections
This commit is contained in:
@@ -136,7 +136,7 @@ export function resolveTargetType(
|
||||
|
||||
// 4. Check profile config
|
||||
if (profileConfig?.target) {
|
||||
// Persisted targets intentionally exclude runtime-only codex.
|
||||
// Persisted targets are validated before profile configuration is saved.
|
||||
return profileConfig.target;
|
||||
}
|
||||
|
||||
|
||||
@@ -483,9 +483,8 @@ export async function reconcileExhaustedRotationAccounts(
|
||||
return [];
|
||||
}
|
||||
|
||||
const { pauseAccountForQuotaCooldown, restoreExpiredQuotaPauses } = await import(
|
||||
'../accounts/account-safety'
|
||||
);
|
||||
const { pauseAccountForQuotaCooldown, restoreExpiredQuotaPauses } =
|
||||
await import('../accounts/account-safety');
|
||||
restoreExpiredQuotaPauses();
|
||||
|
||||
const config = loadOrCreateUnifiedConfig();
|
||||
@@ -593,9 +592,8 @@ export async function preflightCheck(provider: CLIProxyProvider): Promise<Prefli
|
||||
return { proceed: true, accountId: defaultAccount?.id || '' };
|
||||
}
|
||||
|
||||
const { pauseAccountForQuotaCooldown, restoreExpiredQuotaPauses } = await import(
|
||||
'../accounts/account-safety'
|
||||
);
|
||||
const { pauseAccountForQuotaCooldown, restoreExpiredQuotaPauses } =
|
||||
await import('../accounts/account-safety');
|
||||
restoreExpiredQuotaPauses();
|
||||
|
||||
const config = loadOrCreateUnifiedConfig();
|
||||
|
||||
@@ -62,7 +62,7 @@ export async function showApiCommandHelp(writeLine: HelpWriter = console.log): P
|
||||
` ${color('--1m / --no-1m', 'command')} Write or clear [1m] on compatible Claude mappings`
|
||||
);
|
||||
writeLine(
|
||||
` ${color('--target <cli>', 'command')} Default target: claude or droid (create)`
|
||||
` ${color('--target <cli>', 'command')} Default target: claude, droid, or codex (create)`
|
||||
);
|
||||
writeLine(` ${color('--register', 'command')} Register discovered orphan settings`);
|
||||
writeLine(` ${color('--json', 'command')} JSON output for discover command`);
|
||||
|
||||
@@ -112,9 +112,8 @@ export async function runImageAnalysisCheck(results: HealthCheck): Promise<void>
|
||||
* Fix image analysis configuration issues
|
||||
*/
|
||||
export async function fixImageAnalysisConfig(): Promise<boolean> {
|
||||
const { updateConfig, loadOrCreateUnifiedConfig } = await import(
|
||||
'../../config/config-loader-facade'
|
||||
);
|
||||
const { updateConfig, loadOrCreateUnifiedConfig } =
|
||||
await import('../../config/config-loader-facade');
|
||||
|
||||
const config = loadOrCreateUnifiedConfig();
|
||||
let fixed = false;
|
||||
|
||||
@@ -23,7 +23,7 @@ export const TARGET_METADATA: Record<TargetType, TargetMetadata> = {
|
||||
displayName: 'Codex CLI',
|
||||
runtimeAliases: ['ccs-codex', 'ccsx', 'ccsxp'],
|
||||
legacyAliasEnvVar: 'CCS_CODEX_ALIASES',
|
||||
persistedTarget: false,
|
||||
persistedTarget: true,
|
||||
},
|
||||
} satisfies Record<TargetType, TargetMetadata>;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ describe('profile reader target sanitization', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('normalizes legacy stored codex targets back to claude for profiles and variants', async () => {
|
||||
it('normalizes legacy invalid stored targets back to claude for profiles and variants', async () => {
|
||||
const ccsDir = getScopedCcsDir();
|
||||
fs.mkdirSync(ccsDir, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
@@ -64,12 +64,12 @@ describe('profile reader target sanitization', () => {
|
||||
JSON.stringify(
|
||||
{
|
||||
profiles: { demo: '~/.ccs/demo.settings.json' },
|
||||
profile_targets: { demo: 'codex' },
|
||||
profile_targets: { demo: 'glm' },
|
||||
cliproxy: {
|
||||
routed: {
|
||||
provider: 'codex',
|
||||
settings: '~/.ccs/routed.settings.json',
|
||||
target: 'codex',
|
||||
target: 'glm',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -94,7 +94,7 @@ describe('profile reader target sanitization', () => {
|
||||
expect(result.variants[0]?.target).toBe('claude');
|
||||
});
|
||||
|
||||
it('normalizes unified stored codex targets back to claude for profiles and variants', async () => {
|
||||
it('normalizes unified invalid stored targets back to claude for profiles and variants', async () => {
|
||||
const ccsDir = getScopedCcsDir();
|
||||
fs.mkdirSync(ccsDir, { recursive: true });
|
||||
process.env.CCS_UNIFIED_CONFIG = '1';
|
||||
@@ -106,7 +106,7 @@ describe('profile reader target sanitization', () => {
|
||||
' demo:',
|
||||
' type: api',
|
||||
' settings: ~/.ccs/demo.settings.json',
|
||||
' target: codex',
|
||||
' target: glm',
|
||||
'cliproxy:',
|
||||
' oauth_accounts: {}',
|
||||
' providers: []',
|
||||
@@ -114,7 +114,7 @@ describe('profile reader target sanitization', () => {
|
||||
' routed:',
|
||||
' provider: codex',
|
||||
' settings: ~/.ccs/routed.settings.json',
|
||||
' target: codex',
|
||||
' target: glm',
|
||||
'',
|
||||
].join('\n'),
|
||||
'utf8'
|
||||
|
||||
@@ -71,15 +71,15 @@ describe('api-command arg parser', () => {
|
||||
|
||||
expect(parsed.target).toBeUndefined();
|
||||
expect(parsed.errors).toEqual([
|
||||
'Invalid --target value "invalid-target". Use: claude or droid',
|
||||
'Invalid --target value "invalid-target". Use: claude, droid, or codex',
|
||||
]);
|
||||
});
|
||||
|
||||
test('rejects runtime-only codex as a persisted API target value', () => {
|
||||
test('accepts codex as a persisted API target value', () => {
|
||||
const parsed = parseApiCommandArgs(['my-api', '--target', 'codex']);
|
||||
|
||||
expect(parsed.target).toBeUndefined();
|
||||
expect(parsed.errors).toEqual(['Invalid --target value "codex". Use: claude or droid']);
|
||||
expect(parsed.target).toBe('codex');
|
||||
expect(parsed.errors).toEqual([]);
|
||||
});
|
||||
|
||||
test('collects missing-value error for --target with no value', () => {
|
||||
|
||||
@@ -26,11 +26,11 @@ describe('cliproxy variant arg parser', () => {
|
||||
expect(parsed.errors).toEqual(['Missing value for --target']);
|
||||
});
|
||||
|
||||
test('rejects runtime-only codex as a persisted variant target value', () => {
|
||||
test('accepts codex as a persisted variant target value', () => {
|
||||
const parsed = parseProfileArgs(['variant-a', '--target', 'codex']);
|
||||
|
||||
expect(parsed.target).toBeUndefined();
|
||||
expect(parsed.errors).toEqual(['Invalid --target value "codex". Use: claude or droid']);
|
||||
expect(parsed.target).toBe('codex');
|
||||
expect(parsed.errors).toEqual([]);
|
||||
});
|
||||
|
||||
test('uses last --target value when repeated', () => {
|
||||
|
||||
@@ -68,9 +68,9 @@ describe('resolveTargetType', () => {
|
||||
expect(resolveTargetType([], { target: 'invalid-target' as never })).toBe('claude');
|
||||
});
|
||||
|
||||
it('should ignore runtime-only codex target when it appears in persisted profile config', () => {
|
||||
it('should use codex from persisted profile config', () => {
|
||||
process.argv = ['node', 'ccs'];
|
||||
expect(resolveTargetType([], { target: 'codex' })).toBe('claude');
|
||||
expect(resolveTargetType([], { target: 'codex' })).toBe('codex');
|
||||
});
|
||||
|
||||
it('should prioritize --target flag over profile config', () => {
|
||||
|
||||
@@ -7,16 +7,16 @@ describe('route target parsing', () => {
|
||||
it('accepts valid target values', () => {
|
||||
expect(parseProfileTarget('claude')).toBe('claude');
|
||||
expect(parseProfileTarget('DROID')).toBe('droid');
|
||||
expect(parseProfileTarget('codex')).toBe('codex');
|
||||
expect(parseVariantTarget(' claude ')).toBe('claude');
|
||||
expect(parseVariantTarget('droid')).toBe('droid');
|
||||
expect(parseVariantTarget(' codex ')).toBe('codex');
|
||||
});
|
||||
|
||||
it('returns null for invalid target values', () => {
|
||||
expect(parseProfileTarget('glm')).toBeNull();
|
||||
expect(parseProfileTarget('codex')).toBeNull();
|
||||
expect(parseProfileTarget('')).toBeNull();
|
||||
expect(parseVariantTarget('factory')).toBeNull();
|
||||
expect(parseVariantTarget('codex')).toBeNull();
|
||||
expect(parseVariantTarget(' ')).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user