Files
claude-code/automation/upgrade.sh
OpenCode Test f1f30bcb2f Add quick reference guide and upgrade script
- docs/QUICK-REFERENCE.md: Comprehensive quick reference card with
  - All commands organized by category
  - Shell aliases
  - Key paths
  - PA flags
  - Autonomy levels
  - Troubleshooting tips
- automation/upgrade.sh: Version upgrade management
  - Check for available upgrades (git-aware)
  - Pre-upgrade backup creation
  - Migration runner for version upgrades
  - Post-upgrade validation
- Updated shell completions with 16 aliases total
- Test suite now covers 24 tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 18:50:04 -08:00

226 lines
5.8 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Upgrade script for Claude Code configuration
# Usage: ./upgrade.sh [--check|--backup|--apply]
set -euo pipefail
CLAUDE_DIR="${HOME}/.claude"
VERSION_FILE="${CLAUDE_DIR}/VERSION"
BACKUP_DIR="${CLAUDE_DIR}/backups"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${BLUE}${NC} $1"; }
ok() { echo -e "${GREEN}${NC} $1"; }
warn() { echo -e "${YELLOW}${NC} $1"; }
error() { echo -e "${RED}${NC} $1"; }
get_current_version() {
if [[ -f "$VERSION_FILE" ]]; then
cat "$VERSION_FILE" | tr -d '\n'
else
echo "0.0.0"
fi
}
compare_versions() {
local v1="$1"
local v2="$2"
# Returns: -1 if v1 < v2, 0 if equal, 1 if v1 > v2
if [[ "$v1" == "$v2" ]]; then
echo "0"
return
fi
local IFS='.'
local i v1_parts=($v1) v2_parts=($v2)
for ((i=0; i<3; i++)); do
local v1_part="${v1_parts[i]:-0}"
local v2_part="${v2_parts[i]:-0}"
if ((v1_part > v2_part)); then
echo "1"
return
elif ((v1_part < v2_part)); then
echo "-1"
return
fi
done
echo "0"
}
check_upgrade() {
local current=$(get_current_version)
echo ""
echo "🔍 Checking for upgrades..."
echo ""
echo " Current version: $current"
echo ""
# Check git status if in a repo
if [[ -d "${CLAUDE_DIR}/.git" ]]; then
cd "$CLAUDE_DIR"
# Fetch latest
if git fetch origin 2>/dev/null; then
local local_hash=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
local remote_hash=$(git rev-parse origin/main 2>/dev/null || echo "unknown")
if [[ "$local_hash" != "$remote_hash" ]] && [[ "$remote_hash" != "unknown" ]]; then
local ahead=$(git rev-list --count origin/main..HEAD 2>/dev/null || echo "0")
local behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo "0")
if [[ "$behind" -gt 0 ]]; then
warn "Behind origin/main by $behind commit(s)"
echo ""
echo " Run: cd ~/.claude && git pull"
fi
if [[ "$ahead" -gt 0 ]]; then
info "Ahead of origin/main by $ahead commit(s)"
fi
else
ok "Up to date with origin/main"
fi
else
warn "Could not fetch from remote"
fi
else
info "Not a git repository - manual upgrade required"
fi
echo ""
}
pre_upgrade_backup() {
echo ""
echo "📦 Creating pre-upgrade backup..."
mkdir -p "$BACKUP_DIR"
local timestamp=$(date +%Y%m%d-%H%M%S)
local backup_file="${BACKUP_DIR}/pre-upgrade-${timestamp}.tar.gz"
# Backup essential files only
tar -czf "$backup_file" \
-C "$CLAUDE_DIR" \
--exclude='backups' \
--exclude='logs' \
--exclude='*.pyc' \
--exclude='__pycache__' \
--exclude='.git' \
--exclude='venv' \
. 2>/dev/null || true
ok "Backup created: $backup_file"
echo ""
}
apply_migrations() {
local current="$1"
local target="$2"
echo ""
echo "🔄 Applying migrations from $current to $target..."
echo ""
# Migration: 0.x.x -> 1.0.0
if [[ $(compare_versions "$current" "1.0.0") -lt 0 ]] && \
[[ $(compare_versions "$target" "1.0.0") -ge 0 ]]; then
info "Migration: Initializing plugin structure..."
# Create directories if missing
mkdir -p "${CLAUDE_DIR}/.claude-plugin"
mkdir -p "${CLAUDE_DIR}/hooks/scripts"
mkdir -p "${CLAUDE_DIR}/state/personal-assistant/memory"
mkdir -p "${CLAUDE_DIR}/state/personal-assistant/history"
ok "Plugin structure initialized"
fi
# Migration: 1.0.x -> 1.1.0
if [[ $(compare_versions "$current" "1.1.0") -lt 0 ]] && \
[[ $(compare_versions "$target" "1.1.0") -ge 0 ]]; then
info "Migration: Adding automation scripts..."
# Ensure automation directory exists
mkdir -p "${CLAUDE_DIR}/automation/systemd"
mkdir -p "${CLAUDE_DIR}/logs"
ok "Automation structure initialized"
fi
echo ""
ok "Migrations complete"
}
run_post_upgrade() {
echo ""
echo "🔧 Running post-upgrade tasks..."
# Make scripts executable
find "${CLAUDE_DIR}/automation" -name "*.sh" -type f -exec chmod +x {} \; 2>/dev/null || true
find "${CLAUDE_DIR}/automation" -name "*.py" -type f -exec chmod +x {} \; 2>/dev/null || true
find "${CLAUDE_DIR}/hooks/scripts" -name "*.sh" -type f -exec chmod +x {} \; 2>/dev/null || true
ok "Scripts made executable"
# Validate
if "${CLAUDE_DIR}/automation/validate-setup.sh" > /dev/null 2>&1; then
ok "Validation passed"
else
warn "Validation had warnings (run claude-validate to see details)"
fi
echo ""
}
show_usage() {
echo "Usage: $0 [--check|--backup|--apply TARGET_VERSION]"
echo ""
echo "Options:"
echo " --check Check for available upgrades"
echo " --backup Create pre-upgrade backup"
echo " --apply Apply migrations (requires TARGET_VERSION)"
echo ""
echo "Examples:"
echo " $0 --check"
echo " $0 --backup && git pull && $0 --apply 1.2.0"
}
# Main
case "${1:-}" in
--check)
check_upgrade
;;
--backup)
pre_upgrade_backup
;;
--apply)
if [[ -z "${2:-}" ]]; then
error "TARGET_VERSION required for --apply"
show_usage
exit 1
fi
pre_upgrade_backup
apply_migrations "$(get_current_version)" "$2"
echo "$2" > "$VERSION_FILE"
run_post_upgrade
ok "Upgrade to $2 complete!"
;;
--help|-h)
show_usage
;;
*)
check_upgrade
;;
esac