Files
ccs/src/commands/cliproxy/install-subcommand.ts
T
kaitranntt b149e252eb refactor(cliproxy): modularize top 4 giant files
Split 4 files exceeding 900 lines into focused modules:

- account-manager.ts (961 → 56 lines): 6 modules in accounts/
  - registry, query, bulk-ops, token-file-ops, types, index
- config-generator.ts (981 → 16 lines): 6 modules in config/
  - generator, port-manager, env-builder, thinking-config, path-resolver, index
- cliproxy-executor.ts (1,180 → 21 lines): 5 modules in executor/
  - index, lifecycle-manager, env-resolver, retry-handler, session-bridge
- cliproxy-command.ts (1,297 → 10 lines): 8 modules in commands/cliproxy/
  - index, auth, quota, variant, install, help, proxy-lifecycle subcommands

Total: 4,419 → 103 lines in original files (97.7% reduction)

Backward compatibility maintained via re-export shims.
Edge case fixes: CLI validation, thinking fallback, provider warning.

BREAKING CHANGES: None - all exports preserved via barrel re-exports.
2026-02-05 15:00:02 -05:00

139 lines
4.5 KiB
TypeScript

/**
* CLIProxy Binary Installation
*
* Handles:
* - ccs cliproxy (show status)
* - ccs cliproxy --install <version>
* - ccs cliproxy --latest
* - ccs cliproxy --update
*/
import { initUI, color, dim, ok, fail, info } from '../../utils/ui';
import {
getBinaryStatus,
checkLatestVersion,
installVersion,
installLatest,
} from '../../cliproxy/services';
import { DEFAULT_BACKEND, BACKEND_CONFIG } from '../../cliproxy/platform-detector';
import { CLIProxyBackend } from '../../cliproxy/types';
function getBackendLabel(backend: CLIProxyBackend): string {
return backend === 'plus' ? 'CLIProxy Plus' : 'CLIProxy';
}
export async function showStatus(verbose: boolean, backend: CLIProxyBackend): Promise<void> {
await initUI();
const status = getBinaryStatus(backend);
console.log('');
const backendLabel = getBackendLabel(backend);
console.log(color(`${backendLabel} Status`, 'primary'));
console.log('');
console.log(
` Backend: ${color(backend, 'info')}${backend === DEFAULT_BACKEND ? dim(' (default)') : ''}`
);
if (status.installed) {
console.log(` Installed: ${color('Yes', 'success')}`);
const versionLabel = status.pinnedVersion
? `${color(`v${status.currentVersion}`, 'info')} ${color('(pinned)', 'warning')}`
: color(`v${status.currentVersion}`, 'info');
console.log(` Version: ${versionLabel}`);
console.log(` Binary: ${dim(status.binaryPath)}`);
} else {
console.log(` Installed: ${color('No', 'error')}`);
console.log(` Fallback: ${color(`v${status.fallbackVersion}`, 'info')}`);
console.log(` ${dim('Run "ccs gemini" or any provider to auto-install')}`);
}
const latestCheck = await checkLatestVersion();
if (latestCheck.success && latestCheck.latestVersion) {
console.log('');
if (latestCheck.updateAvailable) {
if (status.pinnedVersion) {
console.log(
` Latest: ${color(`v${latestCheck.latestVersion}`, 'success')} ${dim('(pinned to v' + status.pinnedVersion + ')')}`
);
console.log('');
console.log(` ${dim('Run "ccs cliproxy --update" to unpin and update')}`);
} else {
console.log(
` Latest: ${color(`v${latestCheck.latestVersion}`, 'success')} ${dim('(update available)')}`
);
console.log('');
console.log(` ${dim('Run "ccs cliproxy --latest" to update')}`);
}
} else {
console.log(
` Latest: ${color(`v${latestCheck.latestVersion}`, 'success')} ${dim('(up to date)')}`
);
}
} else if (verbose && latestCheck.error) {
console.log(` Latest: ${dim(`Could not fetch (${latestCheck.error})`)}`);
}
console.log('');
console.log(dim('Run "ccs cliproxy --help" for all available commands'));
console.log('');
}
export async function handleInstallVersion(
version: string,
verbose: boolean,
backend: CLIProxyBackend
): Promise<void> {
const label = getBackendLabel(backend);
console.log(info(`Installing ${label} v${version}...`));
console.log('');
const result = await installVersion(version, verbose, backend);
if (!result.success) {
console.error('');
console.error(fail(`Failed to install ${label} v${version}`));
console.error(` ${result.error}`);
console.error('');
console.error('Possible causes:');
console.error(' 1. Version does not exist on GitHub');
console.error(' 2. Network connectivity issues');
console.error(' 3. GitHub API rate limiting');
console.error('');
console.error('Check available versions at:');
console.error(` https://github.com/${BACKEND_CONFIG[backend].repo}/releases`);
process.exit(1);
}
console.log('');
console.log(ok(`${label} v${version} installed (pinned)`));
console.log('');
console.log(dim('This version will be used until you run:'));
console.log(
` ${color('ccs cliproxy --update', 'command')} ${dim('# Update to latest and unpin')}`
);
console.log('');
}
export async function handleInstallLatest(
verbose: boolean,
backend: CLIProxyBackend
): Promise<void> {
const label = getBackendLabel(backend);
console.log(info(`Fetching latest ${label} version...`));
const result = await installLatest(verbose, backend);
if (!result.success) {
console.error(fail(`Failed to install latest version: ${result.error}`));
process.exit(1);
}
if (result.error?.startsWith('Already')) {
console.log(ok(result.error));
return;
}
console.log('');
console.log(ok(`${label} updated to v${result.version}`));
console.log(dim('Auto-update is now enabled.'));
console.log('');
}