From d3de83e157b4d286cc9b684339cccbe501b911a3 Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Thu, 16 Apr 2026 23:29:10 -0400 Subject: [PATCH] fix(cliproxy): pin routing config regeneration path - capture the resolved local cliproxy config/auth paths before regenerating routing strategy config - thread explicit override paths into regenerateConfig so scoped config writes stay deterministic during the full test suite - add regression coverage for explicit config path overrides --- src/cliproxy/config/generator.ts | 15 ++++++++++++--- src/cliproxy/routing-strategy.ts | 5 ++++- .../cliproxy/config-generator-port.test.js | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/cliproxy/config/generator.ts b/src/cliproxy/config/generator.ts index 815b81b7..51f59b20 100644 --- a/src/cliproxy/config/generator.ts +++ b/src/cliproxy/config/generator.ts @@ -42,6 +42,11 @@ export const CCS_CONTROL_PANEL_SECRET = 'ccs'; */ export const CLIPROXY_CONFIG_VERSION = 17; +interface RegenerateConfigOptions { + configPath?: string; + authDir?: string; +} + interface OAuthModelAliasEntry { name: string; alias: string; @@ -739,8 +744,12 @@ function extractYamlSection(content: string, sectionKey: string): string { * @param port - Default port to use if not found in existing config * @returns Path to new config file */ -export function regenerateConfig(port: number = CLIPROXY_DEFAULT_PORT): string { - const configPath = getConfigPathForPort(port); +export function regenerateConfig( + port: number = CLIPROXY_DEFAULT_PORT, + options?: RegenerateConfigOptions +): string { + const configPath = options?.configPath ?? getConfigPathForPort(port); + const authDir = options?.authDir ?? getAuthDir(); // Preserve user settings from existing config let effectivePort = port; @@ -787,7 +796,7 @@ export function regenerateConfig(port: number = CLIPROXY_DEFAULT_PORT): string { // Ensure directories exist fs.mkdirSync(path.dirname(configPath), { recursive: true }); - fs.mkdirSync(getAuthDir(), { recursive: true, mode: 0o700 }); + fs.mkdirSync(authDir, { recursive: true, mode: 0o700 }); // Generate fresh config with preserved user API keys and aliases let configContent = generateUnifiedConfigContent(effectivePort, userApiKeys, existingAliases); diff --git a/src/cliproxy/routing-strategy.ts b/src/cliproxy/routing-strategy.ts index 6adb15ff..ff621a9b 100644 --- a/src/cliproxy/routing-strategy.ts +++ b/src/cliproxy/routing-strategy.ts @@ -1,5 +1,6 @@ import { mutateUnifiedConfig, loadOrCreateUnifiedConfig } from '../config/unified-config-loader'; import { regenerateConfig } from './config/generator'; +import { getAuthDir, getConfigPathForPort } from './config/path-resolver'; import { fetchCliproxyRoutingResponse, getCliproxyRoutingTarget, @@ -98,6 +99,8 @@ export async function applyCliproxyRoutingStrategy( strategy: CliproxyRoutingStrategy ): Promise { const target = getCliproxyRoutingTarget(); + const configPath = getConfigPathForPort(target.port); + const authDir = getAuthDir(); if (target.isRemote) { await updateLiveCliproxyRoutingStrategy(strategy); @@ -116,7 +119,7 @@ export async function applyCliproxyRoutingStrategy( config.cliproxy.routing = { strategy }; } }); - regenerateConfig(target.port); + regenerateConfig(target.port, { configPath, authDir }); try { await updateLiveCliproxyRoutingStrategy(strategy); diff --git a/tests/unit/cliproxy/config-generator-port.test.js b/tests/unit/cliproxy/config-generator-port.test.js index dfbb76d5..af291d00 100644 --- a/tests/unit/cliproxy/config-generator-port.test.js +++ b/tests/unit/cliproxy/config-generator-port.test.js @@ -185,6 +185,24 @@ describe('Config Generator Port', function () { // Port should still be 8325 assert.ok(content.includes(`port: ${variantPort}`)); }); + + it('honors an explicit config path override', function () { + const variantPort = 8318; + const overrideDir = path.join(testHome, '.ccs-scope-override', 'cliproxy'); + const overrideConfigPath = path.join(overrideDir, `config-${variantPort}.yaml`); + const overrideAuthDir = path.join(overrideDir, 'auth'); + + regenerateConfig(variantPort, { + configPath: overrideConfigPath, + authDir: overrideAuthDir, + }); + + assert.ok(fs.existsSync(overrideConfigPath), 'Should create config at the override path'); + assert.ok(fs.existsSync(overrideAuthDir), 'Should create auth dir at the override path'); + + const defaultConfigPath = path.join(cliproxyDir, `config-${variantPort}.yaml`); + assert.strictEqual(fs.existsSync(defaultConfigPath), false); + }); }); describe('deleteConfigForPort', function () {