mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-19 10:14:56 +00:00
feat(update): add automatic update check on startup
- check cached update result synchronously on every command - show warnBox notification if update available - skip check for version/help/update commands - refresh cache in background if stale (>24h) - use proper UI components (warnBox) for notification
This commit is contained in:
1 parent
a0751ed604
commit
8a0ad53082
2 files changed
+119
-21
No files matched your search
+70
-13
@@ -1,12 +1,3 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* CCS (Claude Code Switch) - Entry Point
|
||||
*
|
||||
* Instant profile switching for Claude CLI.
|
||||
* Supports multiple accounts, alternative models (GLM, Kimi),
|
||||
* and cost-optimized delegation.
|
||||
*/
|
||||
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -33,6 +24,16 @@ import { handleUpdateCommand } from './commands/update-command';
|
||||
// Import extracted utility functions
|
||||
import { execClaude, escapeShellArg } from './utils/shell-executor';
|
||||
|
||||
// Version and Update check utilities
|
||||
import { getVersion } from './utils/version';
|
||||
import {
|
||||
checkForUpdates,
|
||||
showUpdateNotification,
|
||||
checkCachedUpdate,
|
||||
isCacheStale,
|
||||
} from './utils/update-checker';
|
||||
import { detectInstallationMethod } from './utils/package-manager-detector';
|
||||
|
||||
// ========== Profile Detection ==========
|
||||
|
||||
interface DetectedProfile {
|
||||
@@ -66,7 +67,8 @@ async function execClaudeWithProxy(
|
||||
// 1. Read settings to get API key
|
||||
const settingsPath = getSettingsPath(profileName);
|
||||
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
||||
const apiKey = settings.env.ANTHROPIC_AUTH_TOKEN;
|
||||
const envData = settings.env;
|
||||
const apiKey = envData['ANTHROPIC_AUTH_TOKEN'];
|
||||
|
||||
if (!apiKey || apiKey === 'YOUR_GLM_API_KEY_HERE') {
|
||||
console.error('[X] GLMT profile requires Z.AI API key');
|
||||
@@ -87,7 +89,7 @@ async function execClaudeWithProxy(
|
||||
env: {
|
||||
...process.env,
|
||||
ANTHROPIC_AUTH_TOKEN: apiKey,
|
||||
ANTHROPIC_BASE_URL: settings.env.ANTHROPIC_BASE_URL,
|
||||
ANTHROPIC_BASE_URL: envData['ANTHROPIC_BASE_URL'],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -211,18 +213,73 @@ interface ProfileError extends Error {
|
||||
suggestions?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform background update check (refreshes cache, no notification)
|
||||
*/
|
||||
async function refreshUpdateCache(): Promise<void> {
|
||||
try {
|
||||
const currentVersion = getVersion();
|
||||
const installMethod = detectInstallationMethod();
|
||||
// Force=true to always fetch fresh data
|
||||
await checkForUpdates(currentVersion, true, installMethod);
|
||||
} catch (_e) {
|
||||
// Silently fail - update check shouldn't crash main CLI
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show update notification if cached result indicates update available
|
||||
* Returns true if notification was shown
|
||||
*/
|
||||
async function showCachedUpdateNotification(): Promise<boolean> {
|
||||
try {
|
||||
const currentVersion = getVersion();
|
||||
const updateInfo = checkCachedUpdate(currentVersion);
|
||||
|
||||
if (updateInfo) {
|
||||
await showUpdateNotification(updateInfo);
|
||||
return true;
|
||||
}
|
||||
} catch (_e) {
|
||||
// Silently fail
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const args = process.argv.slice(2);
|
||||
const firstArg = args[0];
|
||||
|
||||
// Trigger update check early for ALL commands except version/help/update
|
||||
// Only if TTY and not CI to avoid noise in automated environments
|
||||
const skipUpdateCheck = [
|
||||
'version',
|
||||
'--version',
|
||||
'-v',
|
||||
'help',
|
||||
'--help',
|
||||
'-h',
|
||||
'update',
|
||||
'--update',
|
||||
];
|
||||
if (process.stdout.isTTY && !process.env['CI'] && !skipUpdateCheck.includes(firstArg)) {
|
||||
// 1. Show cached update notification (async for proper UI)
|
||||
await showCachedUpdateNotification();
|
||||
|
||||
// 2. Refresh cache in background if stale (non-blocking)
|
||||
if (isCacheStale()) {
|
||||
refreshUpdateCache();
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-migrate to unified config format (silent if already migrated)
|
||||
// Skip if user is explicitly running migrate command
|
||||
if (args[0] !== 'migrate') {
|
||||
if (firstArg !== 'migrate') {
|
||||
const { autoMigrate } = await import('./config/migration-manager');
|
||||
await autoMigrate();
|
||||
}
|
||||
|
||||
// Special case: version command (check BEFORE profile detection)
|
||||
const firstArg = args[0];
|
||||
if (firstArg === 'version' || firstArg === '--version' || firstArg === '-v') {
|
||||
handleVersionCommand();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user