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 { checkForUpdates, fetchLatestVersion, isNewerVersion } from './version-checker';
import { downloadAndInstall, deleteBinary, getBinaryPath } from './installer';
import { info } from '../../utils/ui';
import { info, warn } from '../../utils/ui';
import { isCliproxyRunning } from '../stats-fetcher';
import { CLIPROXY_DEFAULT_PORT } from '../config-generator';
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 {
if (isNewerVersion(version, CLIPROXY_MAX_STABLE_VERSION)) {
function isAboveMaxStable(version: string): boolean {
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);
return CLIPROXY_MAX_STABLE_VERSION;
}
@@ -31,17 +43,32 @@ function clampToMaxStable(version: string, verbose: boolean): string {
/** Handle auto-update when binary exists */
async function handleAutoUpdate(config: BinaryManagerConfig, verbose: boolean): Promise<void> {
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;
// Clamp to max stable version
const targetVersion = clampToMaxStable(updateResult.latestVersion, verbose);
if (!isNewerVersion(targetVersion, updateResult.currentVersion)) {
log(`Already at max stable version ${updateResult.currentVersion}`, verbose);
const targetVersion = clampToMaxStable(latestVersion, verbose);
if (!isNewerVersion(targetVersion, currentVersion)) {
log(`Already at max stable version ${currentVersion}`, verbose);
return;
}
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) {
console.log(info(updateMsg));
@@ -95,7 +122,10 @@ export async function ensureBinary(config: BinaryManagerConfig): Promise<string>
config.version = targetVersion;
}
} 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 {
log(`Force version mode: using specified version ${config.version}`, verbose);