Add comprehensive hook installation system and update documentation
Major Features Added: • Automated hook installation scripts (install-hooks.sh and setup-hooks) • User-scope installation with automatic domain configuration • 7 pre-configured hook profiles for different user types • Comprehensive documentation updates across all guides Hook Installation System: • ./setup-hooks - One-liner installation for most users • ./install-hooks.sh - Full-featured installer with profile selection • Automatic domain replacement using $DOMAIN environment variable • Settings backup and verification capabilities • Safe uninstallation with rollback support Documentation Enhancements: • Updated README.md with complete project overview and proper git repository URL • Enhanced Getting Started guide with automated hook installation • Improved Docker deployment guide with hook installation step • Reorganized documentation index with better visual hierarchy • Added repository URL: https://git.supported.systems/claude/claude-code-tracker.git Technical Improvements: • Rebuilt Docker containers with all latest changes • Verified application health and functionality • Updated all installation examples with correct repository URL • Improved quick start workflow with 3-step visual process 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
50c80596d0
commit
1e1d4a995d
8 changed files with 1038 additions and 129 deletions
377
install-hooks.sh
Executable file
377
install-hooks.sh
Executable file
|
|
@ -0,0 +1,377 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Claude Code Tracker - Hook Installation Script
|
||||
# Automatically installs hooks for Claude Code using domain from environment
|
||||
|
||||
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
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CLAUDE_CONFIG_DIR="$HOME/.config/claude-code"
|
||||
CLAUDE_SETTINGS_FILE="$CLAUDE_CONFIG_DIR/settings.json"
|
||||
|
||||
# Hook profiles available
|
||||
AVAILABLE_PROFILES=(
|
||||
"basic"
|
||||
"essential"
|
||||
"comprehensive"
|
||||
"developer"
|
||||
"power_user"
|
||||
"research"
|
||||
"team"
|
||||
)
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ Claude Code Tracker Hooks ║${NC}"
|
||||
echo -e "${BLUE}║ Installation Script ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ${NC} $1"
|
||||
}
|
||||
|
||||
check_requirements() {
|
||||
print_info "Checking requirements..."
|
||||
|
||||
# Check if Claude Code is installed
|
||||
if ! command -v claude-code &> /dev/null; then
|
||||
print_error "Claude Code is not installed or not in PATH"
|
||||
print_info "Please install Claude Code first: https://claude.ai/code"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if jq is available for JSON manipulation
|
||||
if ! command -v jq &> /dev/null; then
|
||||
print_warning "jq is not installed. Using fallback JSON handling."
|
||||
USE_JQ=false
|
||||
else
|
||||
USE_JQ=true
|
||||
fi
|
||||
|
||||
# Check domain configuration
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
# Try to read from .env file
|
||||
if [[ -f "$SCRIPT_DIR/.env" ]]; then
|
||||
source "$SCRIPT_DIR/.env"
|
||||
fi
|
||||
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
print_error "DOMAIN environment variable is not set"
|
||||
print_info "Please set DOMAIN environment variable or create .env file"
|
||||
print_info "Example: export DOMAIN=claude.l.supported.systems"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
print_success "Domain configured: $DOMAIN"
|
||||
print_success "Requirements check passed"
|
||||
}
|
||||
|
||||
create_claude_config_dir() {
|
||||
if [[ ! -d "$CLAUDE_CONFIG_DIR" ]]; then
|
||||
print_info "Creating Claude Code configuration directory..."
|
||||
mkdir -p "$CLAUDE_CONFIG_DIR"
|
||||
print_success "Created directory: $CLAUDE_CONFIG_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
backup_existing_settings() {
|
||||
if [[ -f "$CLAUDE_SETTINGS_FILE" ]]; then
|
||||
local backup_file="${CLAUDE_SETTINGS_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
print_info "Backing up existing settings to: $backup_file"
|
||||
cp "$CLAUDE_SETTINGS_FILE" "$backup_file"
|
||||
print_success "Backup created"
|
||||
fi
|
||||
}
|
||||
|
||||
get_hook_profile_path() {
|
||||
local profile="$1"
|
||||
echo "$SCRIPT_DIR/claude-hooks-${profile}.json"
|
||||
}
|
||||
|
||||
list_available_profiles() {
|
||||
echo -e "${BLUE}Available hook profiles:${NC}"
|
||||
echo ""
|
||||
|
||||
for profile in "${AVAILABLE_PROFILES[@]}"; do
|
||||
local profile_file
|
||||
profile_file=$(get_hook_profile_path "$profile")
|
||||
|
||||
if [[ -f "$profile_file" ]]; then
|
||||
local description
|
||||
if [[ "$USE_JQ" == true ]]; then
|
||||
description=$(jq -r '.metadata.description // "No description available"' "$profile_file" 2>/dev/null || echo "No description available")
|
||||
else
|
||||
description="Hook configuration for $profile users"
|
||||
fi
|
||||
|
||||
echo -e " ${GREEN}$profile${NC} - $description"
|
||||
else
|
||||
echo -e " ${RED}$profile${NC} - Profile file not found"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
update_hook_domain() {
|
||||
local input_file="$1"
|
||||
local output_file="$2"
|
||||
|
||||
print_info "Updating hook URLs with domain: $DOMAIN"
|
||||
|
||||
# Replace placeholder domain with actual domain
|
||||
sed "s/\${DOMAIN}/$DOMAIN/g; s/localhost:8000/$DOMAIN/g; s/http:\/\/$DOMAIN/https:\/\/$DOMAIN/g" "$input_file" > "$output_file"
|
||||
|
||||
print_success "Hook URLs updated"
|
||||
}
|
||||
|
||||
install_hooks() {
|
||||
local profile="$1"
|
||||
local profile_file
|
||||
profile_file=$(get_hook_profile_path "$profile")
|
||||
|
||||
if [[ ! -f "$profile_file" ]]; then
|
||||
print_error "Hook profile file not found: $profile_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_info "Installing hooks from profile: $profile"
|
||||
|
||||
# Create temporary file with updated domain
|
||||
local temp_file="/tmp/claude-hooks-${profile}-$(date +%s).json"
|
||||
update_hook_domain "$profile_file" "$temp_file"
|
||||
|
||||
# Merge with existing settings or create new
|
||||
local final_settings="$temp_file"
|
||||
|
||||
if [[ -f "$CLAUDE_SETTINGS_FILE" ]] && [[ "$USE_JQ" == true ]]; then
|
||||
print_info "Merging with existing Claude Code settings..."
|
||||
|
||||
# Merge hook configurations
|
||||
local merged_file="/tmp/claude-settings-merged-$(date +%s).json"
|
||||
jq -s '.[0] * .[1]' "$CLAUDE_SETTINGS_FILE" "$temp_file" > "$merged_file"
|
||||
final_settings="$merged_file"
|
||||
|
||||
print_success "Settings merged"
|
||||
fi
|
||||
|
||||
# Install the hooks
|
||||
cp "$final_settings" "$CLAUDE_SETTINGS_FILE"
|
||||
|
||||
# Cleanup temp files
|
||||
rm -f "$temp_file"
|
||||
if [[ -f "$merged_file" ]]; then
|
||||
rm -f "$merged_file"
|
||||
fi
|
||||
|
||||
print_success "Hooks installed successfully!"
|
||||
}
|
||||
|
||||
show_installation_summary() {
|
||||
local profile="$1"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Installation Complete! ║${NC}"
|
||||
echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Profile installed:${NC} $profile"
|
||||
echo -e "${BLUE}Domain configured:${NC} $DOMAIN"
|
||||
echo -e "${BLUE}Settings file:${NC} $CLAUDE_SETTINGS_FILE"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Next steps:${NC}"
|
||||
echo "1. Start using Claude Code in any project"
|
||||
echo "2. Visit https://$DOMAIN/dashboard to view your tracking data"
|
||||
echo "3. Check the documentation at https://$DOMAIN/dashboard/docs"
|
||||
echo ""
|
||||
echo -e "${BLUE}To test the installation:${NC}"
|
||||
echo " claude-code --help"
|
||||
echo ""
|
||||
}
|
||||
|
||||
verify_installation() {
|
||||
print_info "Verifying installation..."
|
||||
|
||||
if [[ -f "$CLAUDE_SETTINGS_FILE" ]]; then
|
||||
if [[ "$USE_JQ" == true ]]; then
|
||||
if jq empty "$CLAUDE_SETTINGS_FILE" 2>/dev/null; then
|
||||
print_success "Settings file is valid JSON"
|
||||
|
||||
local hook_count
|
||||
hook_count=$(jq -r '.hooks | length // 0' "$CLAUDE_SETTINGS_FILE" 2>/dev/null || echo "0")
|
||||
print_success "Number of hooks configured: $hook_count"
|
||||
|
||||
return 0
|
||||
else
|
||||
print_error "Settings file contains invalid JSON"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
print_success "Settings file exists"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
print_error "Settings file was not created"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
show_help() {
|
||||
echo "Claude Code Tracker - Hook Installation Script"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS] [PROFILE]"
|
||||
echo ""
|
||||
echo "PROFILE: Hook profile to install (default: comprehensive)"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -l, --list List available profiles"
|
||||
echo " -d, --domain DOMAIN Set the domain (overrides DOMAIN env var)"
|
||||
echo " -h, --help Show this help message"
|
||||
echo " --verify Verify existing installation"
|
||||
echo " --uninstall Remove all hooks from settings"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 # Install comprehensive profile"
|
||||
echo " $0 basic # Install basic profile"
|
||||
echo " $0 -d example.com # Install with custom domain"
|
||||
echo " $0 --list # List available profiles"
|
||||
echo ""
|
||||
echo "Environment Variables:"
|
||||
echo " DOMAIN Target domain for the Claude Code Tracker"
|
||||
echo ""
|
||||
}
|
||||
|
||||
uninstall_hooks() {
|
||||
print_info "Uninstalling Claude Code Tracker hooks..."
|
||||
|
||||
if [[ ! -f "$CLAUDE_SETTINGS_FILE" ]]; then
|
||||
print_warning "No settings file found, nothing to uninstall"
|
||||
return 0
|
||||
fi
|
||||
|
||||
backup_existing_settings
|
||||
|
||||
if [[ "$USE_JQ" == true ]]; then
|
||||
# Remove hooks section but keep other settings
|
||||
jq 'del(.hooks)' "$CLAUDE_SETTINGS_FILE" > "${CLAUDE_SETTINGS_FILE}.tmp"
|
||||
mv "${CLAUDE_SETTINGS_FILE}.tmp" "$CLAUDE_SETTINGS_FILE"
|
||||
print_success "Hooks removed from settings"
|
||||
else
|
||||
print_warning "Cannot automatically remove hooks without jq. Manual removal required."
|
||||
print_info "Edit $CLAUDE_SETTINGS_FILE and remove the 'hooks' section"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local profile="comprehensive"
|
||||
local list_profiles=false
|
||||
local verify_only=false
|
||||
local uninstall_only=false
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
-l|--list)
|
||||
list_profiles=true
|
||||
shift
|
||||
;;
|
||||
-d|--domain)
|
||||
DOMAIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--verify)
|
||||
verify_only=true
|
||||
shift
|
||||
;;
|
||||
--uninstall)
|
||||
uninstall_only=true
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
print_error "Unknown option: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
profile="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
print_header
|
||||
|
||||
# Handle special modes
|
||||
if [[ "$list_profiles" == true ]]; then
|
||||
check_requirements
|
||||
list_available_profiles
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$verify_only" == true ]]; then
|
||||
check_requirements
|
||||
verify_installation
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [[ "$uninstall_only" == true ]]; then
|
||||
check_requirements
|
||||
create_claude_config_dir
|
||||
uninstall_hooks
|
||||
print_success "Uninstallation complete"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Main installation flow
|
||||
check_requirements
|
||||
create_claude_config_dir
|
||||
backup_existing_settings
|
||||
|
||||
# Validate profile
|
||||
if [[ ! " ${AVAILABLE_PROFILES[@]} " =~ " $profile " ]]; then
|
||||
print_error "Unknown profile: $profile"
|
||||
echo ""
|
||||
list_available_profiles
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install hooks
|
||||
install_hooks "$profile"
|
||||
|
||||
# Verify installation
|
||||
if verify_installation; then
|
||||
show_installation_summary "$profile"
|
||||
else
|
||||
print_error "Installation verification failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function with all arguments
|
||||
main "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue