claude-hooks/scripts/uninstall.py
Ryan Malloy 9445e09c48 Add NPM distribution support with hybrid installation approach
Major changes:
- Add package.json with NPM packaging configuration
- Create Node.js CLI interface (bin/claude-hooks.js) with full command set
- Convert bash scripts to Python for better npm integration
- Add npm postinstall/preuninstall hooks for automatic setup
- Update bootstrap prompt to recommend NPM method with git fallback
- Enhance README with NPM-first documentation
- Maintain backward compatibility with existing git installation

Features:
- npm install -g claude-hooks for easy distribution
- claude-hooks init/status/test/backup/uninstall commands
- Automatic Python dependency installation
- Conflict detection and prevention
- Hybrid approach supporting both npm and git workflows

This resolves installation complexity while maintaining developer flexibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 21:03:13 -06:00

110 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Claude Hooks Uninstallation Script for NPM Distribution"""
import os
import sys
import json
import shutil
from pathlib import Path
# 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 Code Hooks Uninstallation", Colors.BLUE)
print("=" * 40)
# Configuration paths
claude_config_dir = Path.home() / ".config" / "claude"
hooks_config_file = claude_config_dir / "hooks.json"
settings_file = claude_config_dir / "settings.json"
# Check if hooks are installed
if not hooks_config_file.exists():
print_status("No Claude Hooks configuration found", "WARNING")
print("Nothing to uninstall.")
return 0
print_colored("This will remove Claude Hooks configuration:", Colors.YELLOW)
print(f"- Remove hooks configuration: {hooks_config_file}")
print("- Remove hooks from Claude settings (if present)")
print("- Preserve hook data and backups")
print()
response = input("Continue with uninstallation? (y/n): ").lower()
if response != 'y':
print("Uninstallation cancelled.")
return 0
# Remove hooks configuration
print("Removing hooks configuration...")
try:
hooks_config_file.unlink()
print_status("Hooks configuration removed", "SUCCESS")
except FileNotFoundError:
print_status("Hooks configuration not found", "WARNING")
except Exception as e:
print_status(f"Error removing hooks configuration: {e}", "ERROR")
return 1
# Remove from Claude settings if it exists
if settings_file.exists():
print("Removing hooks from Claude settings...")
try:
with open(settings_file, 'r') as f:
settings = json.load(f)
if 'hooks' in settings:
# Backup settings
backup_file = settings_file.with_suffix('.json.backup')
shutil.copy2(settings_file, backup_file)
# Remove hooks key
del settings['hooks']
# Write back
with open(settings_file, 'w') as f:
json.dump(settings, f, indent=2)
print_status("Hooks removed from Claude settings", "SUCCESS")
else:
print_status("No hooks found in Claude settings", "WARNING")
except json.JSONDecodeError:
print_status("Could not parse Claude settings file", "WARNING")
except Exception as e:
print_status(f"Error updating Claude settings: {e}", "WARNING")
else:
print_status("No Claude settings file found", "WARNING")
print()
print_colored("Uninstallation Complete!", Colors.GREEN)
print()
print_colored("Next Steps:", Colors.BLUE)
print("1. Restart Claude Code to deactivate hooks")
print("2. Hook data and backups are preserved in case you reinstall")
print("3. To completely remove the package: npm uninstall -g claude-hooks")
print()
print_colored("Note: To completely remove all data, delete hook directories manually", Colors.YELLOW)
return 0
if __name__ == "__main__":
sys.exit(main())