fix(cliproxy): add edge case handling for version capping

- Add isAboveMaxStable() helper for version stability checks
- Add null/empty guard in clampToMaxStable() function
- Warn users on unstable v81+ without forcing downgrade
- Add context note showing latest version when it's unstable
- Clamp fallback version on GitHub API failure
This commit is contained in:
kaitranntt
2026-01-05 11:50:06 -05:00
parent 869ab3eecd
commit 212aef81bc
+39 -9
View File
@@ -7,7 +7,7 @@ import * as fs from 'fs';
import { BinaryManagerConfig } from '../types'; import { BinaryManagerConfig } from '../types';
import { checkForUpdates, fetchLatestVersion, isNewerVersion } from './version-checker'; import { checkForUpdates, fetchLatestVersion, isNewerVersion } from './version-checker';
import { downloadAndInstall, deleteBinary, getBinaryPath } from './installer'; import { downloadAndInstall, deleteBinary, getBinaryPath } from './installer';
import { info } from '../../utils/ui'; import { info, warn } from '../../utils/ui';
import { isCliproxyRunning } from '../stats-fetcher'; import { isCliproxyRunning } from '../stats-fetcher';
import { CLIPROXY_DEFAULT_PORT } from '../config-generator'; import { CLIPROXY_DEFAULT_PORT } from '../config-generator';
import { CLIPROXY_MAX_STABLE_VERSION } from '../platform-detector'; import { CLIPROXY_MAX_STABLE_VERSION } from '../platform-detector';
@@ -18,10 +18,22 @@ function log(message: string, verbose: boolean): void {
} }
/** /**
* Clamp version to max stable if newer versions are unstable * Check if version is above max stable (known unstable)
*/ */
function clampToMaxStable(version: string, verbose: boolean): string { function isAboveMaxStable(version: string): boolean {
if (isNewerVersion(version, CLIPROXY_MAX_STABLE_VERSION)) { return isNewerVersion(version, CLIPROXY_MAX_STABLE_VERSION);
}
/**
* Clamp version to max stable if newer versions are unstable
* Returns max stable version if input is empty/invalid
*/
function clampToMaxStable(version: string | undefined, verbose: boolean): string {
if (!version) {
log(`Empty version, using max stable ${CLIPROXY_MAX_STABLE_VERSION}`, verbose);
return CLIPROXY_MAX_STABLE_VERSION;
}
if (isAboveMaxStable(version)) {
log(`Clamping ${version} to max stable ${CLIPROXY_MAX_STABLE_VERSION}`, verbose); log(`Clamping ${version} to max stable ${CLIPROXY_MAX_STABLE_VERSION}`, verbose);
return CLIPROXY_MAX_STABLE_VERSION; return CLIPROXY_MAX_STABLE_VERSION;
} }
@@ -31,17 +43,32 @@ function clampToMaxStable(version: string, verbose: boolean): string {
/** Handle auto-update when binary exists */ /** Handle auto-update when binary exists */
async function handleAutoUpdate(config: BinaryManagerConfig, verbose: boolean): Promise<void> { async function handleAutoUpdate(config: BinaryManagerConfig, verbose: boolean): Promise<void> {
const updateResult = await checkForUpdates(config.binPath, config.version, verbose); const updateResult = await checkForUpdates(config.binPath, config.version, verbose);
const currentVersion = updateResult.currentVersion;
const latestVersion = updateResult.latestVersion;
// Check if user is on known unstable version - inform but don't force downgrade
if (isAboveMaxStable(currentVersion)) {
console.log(
warn(
`CLIProxy Plus v${currentVersion} has known stability issues. ` +
`Stable version: v${CLIPROXY_MAX_STABLE_VERSION}`
)
);
console.log(info('Run "ccs cliproxy install 80" to downgrade, or wait for upstream fix'));
}
if (!updateResult.hasUpdate) return; if (!updateResult.hasUpdate) return;
// Clamp to max stable version // Clamp to max stable version
const targetVersion = clampToMaxStable(updateResult.latestVersion, verbose); const targetVersion = clampToMaxStable(latestVersion, verbose);
if (!isNewerVersion(targetVersion, updateResult.currentVersion)) { if (!isNewerVersion(targetVersion, currentVersion)) {
log(`Already at max stable version ${updateResult.currentVersion}`, verbose); log(`Already at max stable version ${currentVersion}`, verbose);
return; return;
} }
const proxyRunning = await isCliproxyRunning(CLIPROXY_DEFAULT_PORT); const proxyRunning = await isCliproxyRunning(CLIPROXY_DEFAULT_PORT);
const updateMsg = `CLIProxy Plus update available: v${updateResult.currentVersion} -> v${targetVersion}`; const latestNote = isAboveMaxStable(latestVersion) ? ` (latest v${latestVersion} unstable)` : '';
const updateMsg = `CLIProxy Plus update: v${currentVersion} -> v${targetVersion}${latestNote}`;
if (proxyRunning) { if (proxyRunning) {
console.log(info(updateMsg)); console.log(info(updateMsg));
@@ -95,7 +122,10 @@ export async function ensureBinary(config: BinaryManagerConfig): Promise<string>
config.version = targetVersion; config.version = targetVersion;
} }
} catch { } catch {
log(`Using pinned version: ${config.version}`, verbose); // API failed - use fallback but still clamp to max stable
const fallbackVersion = clampToMaxStable(config.version, verbose);
config.version = fallbackVersion;
log(`Using fallback version: ${fallbackVersion}`, verbose);
} }
} else { } else {
log(`Force version mode: using specified version ${config.version}`, verbose); log(`Force version mode: using specified version ${config.version}`, verbose);