114 lines
3.7 KiB
Python
114 lines
3.7 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Manual Backup Script for Claude Hooks"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
# Add lib directory to path
|
||
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "lib"))
|
||
|
|
|
||
|
|
try:
|
||
|
|
from backup_manager import BackupManager
|
||
|
|
from session_state import SessionState
|
||
|
|
except ImportError as e:
|
||
|
|
print(f"Error importing backup modules: {e}")
|
||
|
|
print("Please ensure Claude Hooks is properly installed.")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
# Colors for terminal output
|
||
|
|
class Colors:
|
||
|
|
RED = '\033[0;31m'
|
||
|
|
GREEN = '\033[0;32m'
|
||
|
|
YELLOW = '\033[1;33m'
|
||
|
|
BLUE = '\033[0;34m'
|
||
|
|
NC = '\033[0m' # No Color
|
||
|
|
|
||
|
|
def print_colored(message, color):
|
||
|
|
print(f"{color}{message}{Colors.NC}")
|
||
|
|
|
||
|
|
def print_status(message, status="INFO"):
|
||
|
|
colors = {
|
||
|
|
"SUCCESS": Colors.GREEN,
|
||
|
|
"ERROR": Colors.RED,
|
||
|
|
"WARNING": Colors.YELLOW,
|
||
|
|
"INFO": Colors.BLUE
|
||
|
|
}
|
||
|
|
print_colored(f"[{status}] {message}", colors.get(status, Colors.NC))
|
||
|
|
|
||
|
|
def main():
|
||
|
|
print_colored("Claude Hooks Manual Backup", Colors.BLUE)
|
||
|
|
print("=" * 30)
|
||
|
|
|
||
|
|
# Get package root and setup paths
|
||
|
|
package_root = Path(__file__).parent.parent
|
||
|
|
runtime_dir = package_root / ".claude_hooks"
|
||
|
|
|
||
|
|
try:
|
||
|
|
# Initialize backup manager
|
||
|
|
backup_manager = BackupManager(str(runtime_dir / "backups"))
|
||
|
|
session_state = SessionState(str(runtime_dir))
|
||
|
|
|
||
|
|
print("Creating manual backup...")
|
||
|
|
|
||
|
|
# Get current working directory (where user is working)
|
||
|
|
cwd = Path.cwd()
|
||
|
|
print(f"Backing up from: {cwd}")
|
||
|
|
|
||
|
|
# Create backup context
|
||
|
|
backup_context = {
|
||
|
|
"trigger": "manual",
|
||
|
|
"timestamp": datetime.now().isoformat(),
|
||
|
|
"cwd": str(cwd),
|
||
|
|
"session_info": session_state.get_session_summary()
|
||
|
|
}
|
||
|
|
|
||
|
|
# Perform backup
|
||
|
|
backup_id = backup_manager.create_backup(
|
||
|
|
project_path=str(cwd),
|
||
|
|
context=backup_context,
|
||
|
|
force=True # Allow manual backup even if recent backup exists
|
||
|
|
)
|
||
|
|
|
||
|
|
if backup_id:
|
||
|
|
print_status(f"Backup created successfully: {backup_id}", "SUCCESS")
|
||
|
|
|
||
|
|
# Show backup details
|
||
|
|
backup_info = backup_manager.get_backup_info(backup_id)
|
||
|
|
if backup_info:
|
||
|
|
print()
|
||
|
|
print_colored("Backup Details:", Colors.BLUE)
|
||
|
|
print(f"📁 Backup ID: {backup_id}")
|
||
|
|
print(f"📅 Created: {backup_info.get('timestamp', 'Unknown')}")
|
||
|
|
print(f"📂 Location: {backup_info.get('path', 'Unknown')}")
|
||
|
|
|
||
|
|
if 'files_backed_up' in backup_info:
|
||
|
|
file_count = len(backup_info['files_backed_up'])
|
||
|
|
print(f"📄 Files: {file_count}")
|
||
|
|
|
||
|
|
if file_count > 0 and file_count <= 10:
|
||
|
|
print(" Files backed up:")
|
||
|
|
for file_path in backup_info['files_backed_up'][:10]:
|
||
|
|
print(f" - {file_path}")
|
||
|
|
elif file_count > 10:
|
||
|
|
print(" Sample files backed up:")
|
||
|
|
for file_path in backup_info['files_backed_up'][:5]:
|
||
|
|
print(f" - {file_path}")
|
||
|
|
print(f" ... and {file_count - 5} more")
|
||
|
|
|
||
|
|
print()
|
||
|
|
print_colored("Backup completed successfully! 🎉", Colors.GREEN)
|
||
|
|
else:
|
||
|
|
print_status("Backup failed - check logs for details", "ERROR")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print_status(f"Backup error: {e}", "ERROR")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
return 0
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(main())
|