mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-20 05:11:48 +00:00
feat: add 'ccs update' command with smart update notifications
Add comprehensive update functionality with intelligent notification system. Supports manual update checking, automatic notifications every 24h, and works across npm and direct installations with proper error handling. Closes #12
This commit is contained in:
1 parent
31a21d13ad
commit
d34dbcac1f
12 files changed
+686
-18
No files matched your search
@@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Version (updated by scripts/bump-version.sh)
|
||||
CCS_VERSION="4.1.6"
|
||||
CCS_VERSION="4.2.0"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}"
|
||||
readonly PROFILES_JSON="$HOME/.ccs/profiles.json"
|
||||
@@ -199,6 +199,7 @@ show_help() {
|
||||
echo -e "${CYAN}Diagnostics:${RESET}"
|
||||
echo -e " ${YELLOW}ccs doctor${RESET} Run health check and diagnostics"
|
||||
echo -e " ${YELLOW}ccs sync${RESET} Sync delegation commands and skills"
|
||||
echo -e " ${YELLOW}ccs update${RESET} Update CCS to latest version"
|
||||
echo ""
|
||||
|
||||
echo -e "${CYAN}Flags:${RESET}"
|
||||
@@ -591,6 +592,124 @@ sync_run() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
# --- Update Command ---
|
||||
|
||||
update_run() {
|
||||
echo ""
|
||||
echo -e "${CYAN}Checking for updates...${RESET}"
|
||||
echo ""
|
||||
|
||||
# Detect installation method
|
||||
local install_method="direct"
|
||||
if command -v npm &>/dev/null && npm list -g @kaitranntt/ccs &>/dev/null 2>&1; then
|
||||
install_method="npm"
|
||||
fi
|
||||
|
||||
# Fetch latest version from appropriate source
|
||||
local latest_version=""
|
||||
if command -v curl &>/dev/null; then
|
||||
if [[ "$install_method" == "npm" ]]; then
|
||||
# Check npm registry for npm installations
|
||||
latest_version=$(curl -fsSL https://registry.npmjs.org/@kaitranntt/ccs/latest 2>/dev/null | \
|
||||
grep '"version"' | head -1 | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([0-9.]+)".*/\1/')
|
||||
else
|
||||
# Check GitHub releases for direct installations
|
||||
latest_version=$(curl -fsSL https://api.github.com/repos/kaitranntt/ccs/releases/latest 2>/dev/null | \
|
||||
grep '"tag_name"' | sed -E 's/.*"v?([0-9.]+)".*/\1/')
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$latest_version" ]]; then
|
||||
echo -e "${YELLOW}[!] Unable to check for updates${RESET}"
|
||||
echo ""
|
||||
echo "Try manually:"
|
||||
if [[ "$install_method" == "npm" ]]; then
|
||||
echo -e " ${YELLOW}npm install -g @kaitranntt/ccs@latest${RESET}"
|
||||
else
|
||||
echo -e " ${YELLOW}curl -fsSL ccs.kaitran.ca/install | bash${RESET}"
|
||||
fi
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Compare versions
|
||||
if [[ "$latest_version" == "$CCS_VERSION" ]]; then
|
||||
echo -e "${GREEN}[OK] You are already on the latest version (${CCS_VERSION})${RESET}"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if update available
|
||||
local current_major=$(echo "$CCS_VERSION" | cut -d. -f1)
|
||||
local current_minor=$(echo "$CCS_VERSION" | cut -d. -f2)
|
||||
local current_patch=$(echo "$CCS_VERSION" | cut -d. -f3)
|
||||
|
||||
local latest_major=$(echo "$latest_version" | cut -d. -f1)
|
||||
local latest_minor=$(echo "$latest_version" | cut -d. -f2)
|
||||
local latest_patch=$(echo "$latest_version" | cut -d. -f3)
|
||||
|
||||
local is_newer=0
|
||||
if [[ $latest_major -gt $current_major ]]; then
|
||||
is_newer=1
|
||||
elif [[ $latest_major -eq $current_major ]] && [[ $latest_minor -gt $current_minor ]]; then
|
||||
is_newer=1
|
||||
elif [[ $latest_major -eq $current_major ]] && [[ $latest_minor -eq $current_minor ]] && [[ $latest_patch -gt $current_patch ]]; then
|
||||
is_newer=1
|
||||
fi
|
||||
|
||||
if [[ $is_newer -eq 0 ]]; then
|
||||
echo -e "${GREEN}[OK] You are on version ${CCS_VERSION} (latest is ${latest_version})${RESET}"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[i] Update available: ${CCS_VERSION} → ${latest_version}${RESET}"
|
||||
echo ""
|
||||
|
||||
# Perform update based on installation method
|
||||
if [[ "$install_method" == "npm" ]]; then
|
||||
echo -e "${CYAN}Updating via npm...${RESET}"
|
||||
echo ""
|
||||
|
||||
if npm install -g @kaitranntt/ccs@latest; then
|
||||
echo ""
|
||||
echo -e "${GREEN}[OK] Update successful!${RESET}"
|
||||
echo ""
|
||||
echo -e "Run ${YELLOW}ccs --version${RESET} to verify"
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo -e "${RED}[X] Update failed${RESET}"
|
||||
echo ""
|
||||
echo "Try manually:"
|
||||
echo -e " ${YELLOW}npm install -g @kaitranntt/ccs@latest${RESET}"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${CYAN}Updating via installer...${RESET}"
|
||||
echo ""
|
||||
|
||||
if curl -fsSL ccs.kaitran.ca/install | bash; then
|
||||
echo ""
|
||||
echo -e "${GREEN}[OK] Update successful!${RESET}"
|
||||
echo ""
|
||||
echo -e "Run ${YELLOW}ccs --version${RESET} to verify"
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo -e "${RED}[X] Update failed${RESET}"
|
||||
echo ""
|
||||
echo "Try manually:"
|
||||
echo -e " ${YELLOW}curl -fsSL ccs.kaitran.ca/install | bash${RESET}"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Claude CLI Detection Logic ---
|
||||
|
||||
detect_claude_cli() {
|
||||
@@ -1669,6 +1788,12 @@ if [[ $# -gt 0 ]] && [[ "${1}" == "sync" || "${1}" == "--sync" ]]; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# Special case: update command
|
||||
if [[ $# -gt 0 ]] && [[ "${1}" == "update" || "${1}" == "--update" ]]; then
|
||||
update_run
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# Run auto-recovery before main logic
|
||||
auto_recover || {
|
||||
msg_error "Auto-recovery failed. Check permissions."
|
||||
|
||||
+134
-1
@@ -12,7 +12,7 @@ param(
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Version (updated by scripts/bump-version.sh)
|
||||
$CcsVersion = "4.1.6"
|
||||
$CcsVersion = "4.2.0"
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" }
|
||||
$ProfilesJson = "$env:USERPROFILE\.ccs\profiles.json"
|
||||
@@ -246,6 +246,7 @@ function Show-Help {
|
||||
Write-ColorLine "Diagnostics:" "Cyan"
|
||||
Write-ColorLine " ccs doctor Run health check and diagnostics" "Yellow"
|
||||
Write-ColorLine " ccs sync Sync delegation commands and skills" "Yellow"
|
||||
Write-ColorLine " ccs update Update CCS to latest version" "Yellow"
|
||||
Write-Host ""
|
||||
|
||||
Write-ColorLine "Flags:" "Cyan"
|
||||
@@ -1031,6 +1032,132 @@ function Sync-Run {
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# --- Update Command ---
|
||||
|
||||
function Update-Run {
|
||||
Write-Host ""
|
||||
Write-Host "Checking for updates..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Detect installation method
|
||||
$InstallMethod = "direct"
|
||||
try {
|
||||
$NpmList = npm list -g @kaitranntt/ccs 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$InstallMethod = "npm"
|
||||
}
|
||||
} catch {
|
||||
# npm not available or not installed via npm
|
||||
}
|
||||
|
||||
# Fetch latest version from appropriate source
|
||||
$LatestVersion = ""
|
||||
try {
|
||||
if ($InstallMethod -eq "npm") {
|
||||
# Check npm registry for npm installations
|
||||
$Response = Invoke-RestMethod -Uri "https://registry.npmjs.org/@kaitranntt/ccs/latest" -TimeoutSec 5
|
||||
$LatestVersion = $Response.version
|
||||
} else {
|
||||
# Check GitHub releases for direct installations
|
||||
$Response = Invoke-RestMethod -Uri "https://api.github.com/repos/kaitranntt/ccs/releases/latest" -TimeoutSec 5
|
||||
$LatestVersion = $Response.tag_name -replace '^v', ''
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[!] Unable to check for updates" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Try manually:"
|
||||
if ($InstallMethod -eq "npm") {
|
||||
Write-Host " npm install -g @kaitranntt/ccs@latest" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " irm ccs.kaitran.ca/install | iex" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Compare versions
|
||||
if ($LatestVersion -eq $CcsVersion) {
|
||||
Write-Host "[OK] You are already on the latest version ($CcsVersion)" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check if update available
|
||||
$CurrentParts = $CcsVersion.Split('.')
|
||||
$LatestParts = $LatestVersion.Split('.')
|
||||
|
||||
$IsNewer = $false
|
||||
for ($i = 0; $i -lt 3; $i++) {
|
||||
$Current = [int]$CurrentParts[$i]
|
||||
$Latest = [int]$LatestParts[$i]
|
||||
|
||||
if ($Latest -gt $Current) {
|
||||
$IsNewer = $true
|
||||
break
|
||||
} elseif ($Latest -lt $Current) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $IsNewer) {
|
||||
Write-Host "[OK] You are on version $CcsVersion (latest is $LatestVersion)" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host "[i] Update available: $CcsVersion → $LatestVersion" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
# Perform update based on installation method
|
||||
if ($InstallMethod -eq "npm") {
|
||||
Write-Host "Updating via npm..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
try {
|
||||
npm install -g @kaitranntt/ccs@latest
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ""
|
||||
Write-Host "[OK] Update successful!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Run ccs --version to verify" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
exit 0
|
||||
} else {
|
||||
throw "npm install failed"
|
||||
}
|
||||
} catch {
|
||||
Write-Host ""
|
||||
Write-Host "[X] Update failed" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Try manually:"
|
||||
Write-Host " npm install -g @kaitranntt/ccs@latest" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
Write-Host "Updating via installer..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
try {
|
||||
irm ccs.kaitran.ca/install | iex
|
||||
Write-Host ""
|
||||
Write-Host "[OK] Update successful!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Run ccs --version to verify" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
exit 0
|
||||
} catch {
|
||||
Write-Host ""
|
||||
Write-Host "[X] Update failed" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Try manually:"
|
||||
Write-Host " irm ccs.kaitran.ca/install | iex" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Auth Commands (Phase 3) ---
|
||||
|
||||
function Show-AuthHelp {
|
||||
@@ -1519,6 +1646,12 @@ if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "sync" -or $Remaining
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Special case: update command
|
||||
if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "update" -or $RemainingArgs[0] -eq "--update")) {
|
||||
Update-Run
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Run auto-recovery before main logic
|
||||
if (-not (Invoke-AutoRecovery)) {
|
||||
Write-ErrorMsg "Auto-recovery failed. Check permissions."
|
||||
|
||||
Reference in new issue
Block a user