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>
220 lines
6.8 KiB
Bash
Executable File
220 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Claude Hooks Installation Script
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
CLAUDE_HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
CLAUDE_CONFIG_DIR="$HOME/.config/claude"
|
|
HOOKS_CONFIG_FILE="$CLAUDE_CONFIG_DIR/hooks.json"
|
|
|
|
echo -e "${BLUE}Claude Code Hooks Installation${NC}"
|
|
echo "=================================="
|
|
|
|
# Check for existing installation
|
|
echo -n "Checking for existing Claude Hooks installation... "
|
|
if [ -f "$HOOKS_CONFIG_FILE" ] || command -v claude-hooks >/dev/null 2>&1; then
|
|
echo -e "${RED}CONFLICT DETECTED${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}⚠️ Claude Hooks is already installed!${NC}"
|
|
echo " This would create conflicts since hooks are user-wide."
|
|
echo ""
|
|
echo -e "${BLUE}To proceed:${NC}"
|
|
echo "1. Uninstall existing hooks: claude-hooks uninstall"
|
|
echo "2. Or manually remove: rm -rf ~/.config/claude/hooks.json ~/.local/bin/claude-hooks"
|
|
echo "3. Then run this installer again"
|
|
echo ""
|
|
exit 1
|
|
else
|
|
echo -e "${GREEN}No conflicts found${NC}"
|
|
fi
|
|
|
|
# Check Python version
|
|
echo -n "Checking Python version... "
|
|
if ! python3 --version >/dev/null 2>&1; then
|
|
echo -e "${RED}FAILED${NC}"
|
|
echo "Python 3 is required but not found. Please install Python 3.8 or later."
|
|
exit 1
|
|
fi
|
|
|
|
PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
|
|
echo -e "${GREEN}Python $PYTHON_VERSION found${NC}"
|
|
|
|
# Check if Python version is 3.8+
|
|
if python3 -c "import sys; exit(0 if sys.version_info >= (3, 8) else 1)"; then
|
|
echo -e "${GREEN}✓ Python version is compatible${NC}"
|
|
else
|
|
echo -e "${RED}✗ Python 3.8+ required, found $PYTHON_VERSION${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Install Python dependencies
|
|
echo -n "Installing Python dependencies... "
|
|
if pip3 install -r "$CLAUDE_HOOKS_DIR/requirements.txt" >/dev/null 2>&1; then
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
else
|
|
echo -e "${YELLOW}WARNING${NC}"
|
|
echo "Some dependencies may not have installed. Continuing..."
|
|
fi
|
|
|
|
# Create Claude config directory
|
|
echo -n "Creating Claude config directory... "
|
|
mkdir -p "$CLAUDE_CONFIG_DIR"
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
|
|
# Generate hooks configuration
|
|
echo -n "Generating hooks configuration... "
|
|
sed "s|{{INSTALL_PATH}}|$CLAUDE_HOOKS_DIR|g" "$CLAUDE_HOOKS_DIR/config/hooks.json.template" > "$HOOKS_CONFIG_FILE"
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
|
|
# Make scripts executable
|
|
echo -n "Setting script permissions... "
|
|
chmod +x "$CLAUDE_HOOKS_DIR/hooks/"*.py
|
|
chmod +x "$CLAUDE_HOOKS_DIR/scripts/"*.sh
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
|
|
# Create runtime directories
|
|
echo -n "Creating runtime directories... "
|
|
mkdir -p "$CLAUDE_HOOKS_DIR/.claude_hooks/"{backups,logs,patterns}
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
|
|
# Create claude-hooks command
|
|
echo -n "Creating claude-hooks command... "
|
|
mkdir -p "$HOME/.local/bin"
|
|
cat > "$HOME/.local/bin/claude-hooks" << 'EOF'
|
|
#!/bin/bash
|
|
# Claude Hooks Command Line Interface
|
|
|
|
CLAUDE_HOOKS_DIR="$(dirname "$(readlink -f "$0")")/../.."
|
|
if [ ! -d "$CLAUDE_HOOKS_DIR/claude-hooks" ]; then
|
|
# Fallback: look for installation in common locations
|
|
for dir in "/opt/claude-hooks" "$HOME/claude-hooks" "$HOME/.local/share/claude-hooks"; do
|
|
if [ -d "$dir" ]; then
|
|
CLAUDE_HOOKS_DIR="$dir"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
case "$1" in
|
|
"status")
|
|
echo "Claude Hooks Status:"
|
|
if [ -f "$HOME/.config/claude/hooks.json" ]; then
|
|
echo "✓ Hooks configuration installed"
|
|
else
|
|
echo "✗ No hooks configuration found"
|
|
fi
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
echo "✓ Python 3 available"
|
|
else
|
|
echo "✗ Python 3 not found"
|
|
fi
|
|
;;
|
|
"uninstall")
|
|
if [ -f "$CLAUDE_HOOKS_DIR/claude-hooks/scripts/uninstall.sh" ]; then
|
|
exec "$CLAUDE_HOOKS_DIR/claude-hooks/scripts/uninstall.sh"
|
|
else
|
|
echo "Error: Uninstall script not found"
|
|
echo "Manual removal: rm -rf ~/.config/claude/hooks.json ~/.local/bin/claude-hooks"
|
|
exit 1
|
|
fi
|
|
;;
|
|
"test")
|
|
if [ -f "$CLAUDE_HOOKS_DIR/claude-hooks/scripts/test.sh" ]; then
|
|
exec "$CLAUDE_HOOKS_DIR/claude-hooks/scripts/test.sh"
|
|
else
|
|
echo "Error: Test script not found"
|
|
exit 1
|
|
fi
|
|
;;
|
|
*)
|
|
echo "Claude Hooks CLI"
|
|
echo "Usage: claude-hooks {status|uninstall|test}"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " status - Show installation status"
|
|
echo " uninstall - Remove Claude Hooks"
|
|
echo " test - Run hook tests"
|
|
;;
|
|
esac
|
|
EOF
|
|
|
|
chmod +x "$HOME/.local/bin/claude-hooks"
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
|
|
# Test hook scripts
|
|
echo -n "Testing hook scripts... "
|
|
if python3 "$CLAUDE_HOOKS_DIR/hooks/context_monitor.py" <<< '{"prompt": "test"}' >/dev/null 2>&1; then
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
else
|
|
echo -e "${YELLOW}WARNING${NC}"
|
|
echo "Hook scripts may have issues. Check logs for details."
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}Installation Complete!${NC}"
|
|
echo ""
|
|
echo "📁 Installation directory: $CLAUDE_HOOKS_DIR"
|
|
echo "⚙️ Configuration file: $HOOKS_CONFIG_FILE"
|
|
echo ""
|
|
echo -e "${BLUE}Next Steps:${NC}"
|
|
echo "1. Add the hooks configuration to your Claude Code settings"
|
|
echo "2. Restart Claude Code to load the hooks"
|
|
echo "3. Test with: ./scripts/test.sh"
|
|
echo ""
|
|
echo -e "${BLUE}Configuration to add to Claude Code:${NC}"
|
|
echo "Copy the contents of: $HOOKS_CONFIG_FILE"
|
|
echo ""
|
|
echo -e "${YELLOW}Note:${NC} The hooks will start learning from your usage patterns automatically."
|
|
|
|
# Offer to add to Claude settings automatically if possible
|
|
if [ -f "$HOME/.config/claude/settings.json" ]; then
|
|
echo ""
|
|
read -p "Would you like to automatically add hooks to your Claude settings? (y/n): " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
echo -n "Updating Claude settings... "
|
|
|
|
# Backup existing settings
|
|
cp "$HOME/.config/claude/settings.json" "$HOME/.config/claude/settings.json.backup"
|
|
|
|
# Add hooks configuration
|
|
python3 << EOF
|
|
import json
|
|
|
|
# Read existing settings
|
|
try:
|
|
with open('$HOME/.config/claude/settings.json', 'r') as f:
|
|
settings = json.load(f)
|
|
except:
|
|
settings = {}
|
|
|
|
# Read hooks config
|
|
with open('$HOOKS_CONFIG_FILE', 'r') as f:
|
|
hooks_config = json.load(f)
|
|
|
|
# Merge hooks into settings
|
|
settings.update(hooks_config)
|
|
|
|
# Write back
|
|
with open('$HOME/.config/claude/settings.json', 'w') as f:
|
|
json.dump(settings, f, indent=2)
|
|
|
|
print("Settings updated successfully")
|
|
EOF
|
|
|
|
echo -e "${GREEN}SUCCESS${NC}"
|
|
echo "🎉 Hooks have been automatically configured!"
|
|
echo " Restart Claude Code to activate them."
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}Installation completed successfully!${NC}" |