Added all missing features to extra-tools/install-claude-customizations.sh: New Features: - ✅ Skills installation (from skills/ directory) - ✅ Skills directory creation in ~/.claude/skills/ - ✅ Python script executable permissions for skills - ✅ GitHub agent fetching (fetch_latest_agents function) - ✅ Agent installation from local agents/ directory - ✅ Sync script installation (sync-agents.sh) - ✅ Better directory structure with skills support - ✅ Agent and skill counters - ✅ Enhanced verification with skill counting Changes: - Added SKILLS_DIR configuration variable - Added install_skills() function - Added fetch_latest_agents() function - Updated setup_directories() to include skills/ - Updated install_agents() to copy from local agents/ dir - Enhanced verification to count and report skills - Added --skip-git-fetch option for faster installs Summary: → The extra-tools installer now has feature parity with interactive-install-claude.sh → No functionality missing - both installers are now equivalent → Skills are properly installed with Python scripts made executable → Agents can be fetched from GitHub or installed from local directory Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
509 lines
17 KiB
Bash
Executable File
509 lines
17 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
################################################################################
|
|
# Claude Code Customizations Installer
|
|
# This script automates the setup of custom agents, MCP tools, skills, and plugins
|
|
# for Claude Code on a new machine.
|
|
################################################################################
|
|
|
|
set -e # Exit on error
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
CLAUDE_DIR="$HOME/.claude"
|
|
AGENTS_DIR="$CLAUDE_DIR/agents"
|
|
SKILLS_DIR="$CLAUDE_DIR/skills"
|
|
PLUGINS_DIR="$CLAUDE_DIR/plugins"
|
|
BACKUP_DIR="$HOME/.claude-backup-$(date +%Y%m%d_%H%M%S)"
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
|
|
|
|
# Counters
|
|
AGENTS_INSTALLED=0
|
|
SKILLS_INSTALLED=0
|
|
|
|
################################################################################
|
|
# Helper Functions
|
|
################################################################################
|
|
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
check_command() {
|
|
if ! command -v $1 &> /dev/null; then
|
|
log_error "$1 is not installed. Please install it first."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
backup_file() {
|
|
local file="$1"
|
|
if [ -f "$file" ]; then
|
|
mkdir -p "$BACKUP_DIR"
|
|
cp "$file" "$BACKUP_DIR/"
|
|
log_info "Backed up $file to $BACKUP_DIR"
|
|
fi
|
|
}
|
|
|
|
################################################################################
|
|
# Prerequisites Check
|
|
################################################################################
|
|
|
|
check_prerequisites() {
|
|
log_info "Checking prerequisites..."
|
|
|
|
check_command "node"
|
|
check_command "npm"
|
|
check_command "python3"
|
|
check_command "curl"
|
|
|
|
# Check Node.js version (need 14+)
|
|
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
if [ "$NODE_VERSION" -lt 14 ]; then
|
|
log_error "Node.js version 14 or higher required. Current: $(node -v)"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Prerequisites check passed"
|
|
}
|
|
|
|
################################################################################
|
|
# Directory Structure Setup
|
|
################################################################################
|
|
|
|
setup_directories() {
|
|
log_info "Setting up directory structure..."
|
|
|
|
# Create main directories including skills
|
|
mkdir -p "$CLAUDE_DIR"/{skills,agents,plugins/cache,plugins/marketplaces,hooks,debug,file-history,paste-cache,projects,session-env,shell-snapshots,todos}
|
|
|
|
# Create agent category directories
|
|
mkdir -p "$AGENTS_DIR"/{engineering,marketing,product,studio-operations,project-management,testing,design,bonus}
|
|
|
|
log_success "Directory structure created"
|
|
}
|
|
|
|
################################################################################
|
|
# Fetch Latest Agents from GitHub (Optional)
|
|
################################################################################
|
|
|
|
fetch_latest_agents() {
|
|
log_info "Checking for agent updates from GitHub..."
|
|
|
|
local GITHUB_REPO="https://github.com/contains-studio/agents"
|
|
local TEMP_AGENT_DIR="/tmp/claude-agents-latest-$RANDOM"
|
|
local UPDATE_FOUND=false
|
|
|
|
# Create temp directory
|
|
mkdir -p "$TEMP_AGENT_DIR"
|
|
|
|
# Try to clone using git
|
|
if command -v git &> /dev/null; then
|
|
if git clone --depth 1 --quiet "$GITHUB_REPO" "$TEMP_AGENT_DIR" 2>/dev/null; then
|
|
UPDATE_FOUND=true
|
|
log_success "Fetched latest agents from GitHub"
|
|
|
|
# Copy updated agents to source directory
|
|
for category in engineering marketing product studio-operations project-management testing design bonus; do
|
|
if [ -d "$TEMP_AGENT_DIR/$category" ]; then
|
|
mkdir -p "$SCRIPT_DIR/agents/$category"
|
|
cp -f "$TEMP_AGENT_DIR/$category"/*.md "$SCRIPT_DIR/agents/$category/" 2>/dev/null || true
|
|
fi
|
|
done
|
|
|
|
# Update README if present
|
|
if [ -f "$TEMP_AGENT_DIR/README.md" ]; then
|
|
cp -f "$TEMP_AGENT_DIR/README.md" "$SCRIPT_DIR/agents/README.md" 2>/dev/null || true
|
|
fi
|
|
|
|
log_info "Local agents updated from GitHub"
|
|
else
|
|
log_warning "Failed to fetch from GitHub (using local agents)"
|
|
fi
|
|
else
|
|
log_warning "Git not found (using local agents)"
|
|
fi
|
|
|
|
# Cleanup
|
|
rm -rf "$TEMP_AGENT_DIR"
|
|
|
|
return 0
|
|
}
|
|
|
|
################################################################################
|
|
# Settings Configuration
|
|
################################################################################
|
|
|
|
setup_settings() {
|
|
log_info "Configuring Claude Code settings..."
|
|
|
|
local settings_file="$CLAUDE_DIR/settings.json"
|
|
|
|
backup_file "$settings_file"
|
|
|
|
# Prompt for API credentials
|
|
read -p "Enter your ANTHROPIC_AUTH_TOKEN (or press Enter to skip): " API_TOKEN
|
|
read -p "Enter your ANTHROPIC_BASE_URL (default: https://api.anthropic.com): " API_BASE
|
|
API_BASE=${API_BASE:-https://api.anthropic.com}
|
|
|
|
# Create settings.json
|
|
cat > "$settings_file" << EOF
|
|
{
|
|
"env": {
|
|
"ANTHROPIC_AUTH_TOKEN": "${API_TOKEN}",
|
|
"ANTHROPIC_BASE_URL": "${API_BASE}",
|
|
"API_TIMEOUT_MS": "3000000",
|
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
|
|
},
|
|
"enabledPlugins": {
|
|
"glm-plan-bug@zai-coding-plugins": true,
|
|
"glm-plan-usage@zai-coding-plugins": true
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Create local settings for permissions
|
|
local local_settings="$CLAUDE_DIR/settings.local.json"
|
|
backup_file "$local_settings"
|
|
|
|
cat > "$local_settings" << EOF
|
|
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Bash(npm install:*)",
|
|
"Bash(npm run content:*)",
|
|
"Bash(npm run build:*)",
|
|
"Bash(grep:*)",
|
|
"Bash(find:*)",
|
|
"Bash(for:*)",
|
|
"Bash(do sed:*)",
|
|
"Bash(done)",
|
|
"Bash(python3:*)",
|
|
"Bash(while read f)",
|
|
"Bash(do echo \\"\\$f%-* \\$f\\")",
|
|
"Bash(ls:*)",
|
|
"Bash(node:*)",
|
|
"Bash(pm2 delete:*)",
|
|
"Bash(pm2 start npm:*)",
|
|
"Bash(pm2 save:*)"
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
|
|
log_success "Settings configured"
|
|
}
|
|
|
|
################################################################################
|
|
# MCP Services Installation
|
|
################################################################################
|
|
|
|
install_mcp_services() {
|
|
log_info "Installing MCP services..."
|
|
|
|
# Install @z_ai/mcp-server globally for vision tools
|
|
log_info "Installing @z_ai/mcp-server (vision analysis tools)..."
|
|
npm install -g @z_ai/mcp-server 2>/dev/null || {
|
|
log_warning "Global install failed, trying with npx..."
|
|
# It's okay if this fails, the tools will use npx
|
|
}
|
|
|
|
# Install @z_ai/coding-helper for MCP management
|
|
log_info "Installing @z_ai/coding-helper..."
|
|
npm install -g @z_ai/coding-helper 2>/dev/null || {
|
|
log_warning "Global install failed, will use npx"
|
|
}
|
|
|
|
log_success "MCP services installation completed"
|
|
}
|
|
|
|
################################################################################
|
|
# Agent Installation
|
|
################################################################################
|
|
|
|
install_agents() {
|
|
log_info "Installing custom agents..."
|
|
|
|
local source_agents="$SCRIPT_DIR/agents"
|
|
|
|
if [ ! -d "$source_agents" ]; then
|
|
log_warning "Agent source directory not found at $source_agents"
|
|
log_warning "Agents will not be installed"
|
|
return
|
|
fi
|
|
|
|
# Copy agents from each category
|
|
for category in engineering marketing product studio-operations project-management testing design bonus; do
|
|
if [ -d "$source_agents/$category" ]; then
|
|
mkdir -p "$AGENTS_DIR/$category"
|
|
agent_count=$(cp -f "$source_agents/$category"/*.md "$AGENTS_DIR/$category/" 2>/dev/null | wc -l)
|
|
if [ -d "$AGENTS_DIR/$category" ]; then
|
|
count=$(ls -1 "$AGENTS_DIR/$category"/*.md 2>/dev/null | wc -l)
|
|
AGENTS_INSTALLED=$((AGENTS_INSTALLED + count))
|
|
fi
|
|
fi
|
|
done
|
|
|
|
log_info "Agents installed: $AGENTS_INSTALLED"
|
|
|
|
# Install sync-agents.sh script if available
|
|
if [ -f "$SCRIPT_DIR/extra-tools/sync-agents.sh" ]; then
|
|
log_info "Installing sync-agents.sh script..."
|
|
cp "$SCRIPT_DIR/extra-tools/sync-agents.sh" "$CLAUDE_DIR/sync-agents.sh"
|
|
chmod +x "$CLAUDE_DIR/sync-agents.sh"
|
|
log_success "sync-agents.sh installed (run: ~/.claude/sync-agents.sh)"
|
|
fi
|
|
|
|
log_success "Agent installation completed"
|
|
}
|
|
|
|
################################################################################
|
|
# Skills Installation (NEW - Added from main installer)
|
|
################################################################################
|
|
|
|
install_skills() {
|
|
log_info "Installing skills..."
|
|
|
|
local source_skills="$SCRIPT_DIR/skills"
|
|
|
|
if [ ! -d "$source_skills" ]; then
|
|
log_warning "Skills source directory not found at $source_skills"
|
|
log_warning "Skills will not be installed"
|
|
return
|
|
fi
|
|
|
|
# Create skills directory
|
|
mkdir -p "$SKILLS_DIR"
|
|
|
|
# Copy all skill directories
|
|
for skill_dir in "$source_skills"/*; do
|
|
if [ -d "$skill_dir" ]; then
|
|
skill_name=$(basename "$skill_dir")
|
|
log_info " → Installing skill: $skill_name"
|
|
cp -r "$skill_dir" "$SKILLS_DIR/"
|
|
|
|
# Make Python scripts executable
|
|
if [ -d "$SKILLS_DIR/$skill_name/scripts" ]; then
|
|
chmod +x "$SKILLS_DIR/$skill_name/scripts"/*.py 2>/dev/null || true
|
|
fi
|
|
|
|
SKILLS_INSTALLED=$((SKILLS_INSTALLED + 1))
|
|
fi
|
|
done
|
|
|
|
log_success "✓ Skills installed: $SKILLS_INSTALLED skill(s)"
|
|
log_success "✓ Skills location: $SKILLS_DIR/"
|
|
}
|
|
|
|
################################################################################
|
|
# Plugins Installation
|
|
################################################################################
|
|
|
|
install_plugins() {
|
|
log_info "Installing Claude Code plugins..."
|
|
|
|
# Initialize plugin registry
|
|
local installed_plugins="$PLUGINS_DIR/installed_plugins.json"
|
|
local known_marketplaces="$PLUGINS_DIR/known_marketplaces.json"
|
|
|
|
backup_file "$installed_plugins"
|
|
backup_file "$known_marketplaces"
|
|
|
|
cat > "$known_marketplaces" << EOF
|
|
{
|
|
"marketplaces": {
|
|
"https://github.com/anthropics/claude-plugins": {
|
|
"displayName": "Official Claude Plugins",
|
|
"contact": "support@anthropic.com"
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Install GLM plugins via npx
|
|
log_info "Installing GLM Coding Plan plugins..."
|
|
|
|
# Create plugin cache structure
|
|
mkdir -p "$PLUGINS_DIR/cache/zai-coding-plugins"/{glm-plan-bug,glm-plan-usage}
|
|
|
|
# Note: Actual plugin installation happens via the @z_ai/coding-helper
|
|
# which should already be installed
|
|
|
|
cat > "$installed_plugins" << EOF
|
|
{
|
|
"version": 2,
|
|
"plugins": {
|
|
"glm-plan-bug@zai-coding-plugins": [
|
|
{
|
|
"scope": "user",
|
|
"installPath": "$PLUGINS_DIR/cache/zai-coding-plugins/glm-plan-bug/0.0.1",
|
|
"version": "0.0.1",
|
|
"installedAt": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)",
|
|
"lastUpdated": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"
|
|
}
|
|
],
|
|
"glm-plan-usage@zai-coding-plugins": [
|
|
{
|
|
"scope": "user",
|
|
"installPath": "$PLUGINS_DIR/cache/zai-coding-plugins/glm-plan-usage/0.0.1",
|
|
"version": "0.0.1",
|
|
"installedAt": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)",
|
|
"lastUpdated": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
|
|
log_success "Plugins configured"
|
|
}
|
|
|
|
################################################################################
|
|
# Verification
|
|
################################################################################
|
|
|
|
verify_installation() {
|
|
log_info "Verifying installation..."
|
|
|
|
local errors=0
|
|
|
|
# Check directories
|
|
[ -d "$CLAUDE_DIR" ] || { log_error "Claude directory missing"; errors=$((errors+1)); }
|
|
[ -d "$AGENTS_DIR" ] || { log_error "Agents directory missing"; errors=$((errors+1)); }
|
|
[ -d "$SKILLS_DIR" ] || { log_warning "Skills directory missing (optional)"; }
|
|
[ -d "$PLUGINS_DIR" ] || { log_error "Plugins directory missing"; errors=$((errors+1)); }
|
|
|
|
# Check files
|
|
[ -f "$CLAUDE_DIR/settings.json" ] || { log_error "settings.json missing"; errors=$((errors+1)); }
|
|
[ -f "$CLAUDE_DIR/settings.local.json" ] || { log_error "settings.local.json missing"; errors=$((errors+1)); }
|
|
[ -f "$PLUGINS_DIR/installed_plugins.json" ] || { log_error "installed_plugins.json missing"; errors=$((errors+1)); }
|
|
|
|
# Check MCP availability
|
|
if command -v npx &> /dev/null; then
|
|
log_success "npx available for MCP tools"
|
|
else
|
|
log_error "npx not available"
|
|
errors=$((errors+1))
|
|
fi
|
|
|
|
# Count agents and skills
|
|
if [ -d "$AGENTS_DIR" ]; then
|
|
agent_count=$(find "$AGENTS_DIR" -name "*.md" | wc -l)
|
|
log_success "Agents installed: $agent_count"
|
|
fi
|
|
|
|
if [ -d "$SKILLS_DIR" ]; then
|
|
skill_count=$(find "$SKILLS_DIR" -maxdepth 1 -type d | wc -l)
|
|
skill_count=$((skill_count - 1)) # Subtract 1 for the skills directory itself
|
|
if [ $skill_count -gt 0 ]; then
|
|
log_success "Skills installed: $skill_count skill(s)"
|
|
fi
|
|
fi
|
|
|
|
if [ $errors -eq 0 ]; then
|
|
log_success "Installation verification passed"
|
|
return 0
|
|
else
|
|
log_error "Installation verification failed with $errors errors"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
################################################################################
|
|
# Main Installation Flow
|
|
################################################################################
|
|
|
|
main() {
|
|
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${CYAN}║ Claude Code Customizations - Automated Installer ║${NC}"
|
|
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
# Parse command line arguments
|
|
SKIP_GIT_FETCH=false
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--skip-git-fetch)
|
|
SKIP_GIT_FETCH=true
|
|
shift
|
|
;;
|
|
--help)
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --skip-git-fetch Skip fetching latest agents from GitHub"
|
|
echo " --help Show this help message"
|
|
echo ""
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Unknown option: $1"
|
|
echo "Use --help for usage information"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Run installation steps
|
|
check_prerequisites
|
|
setup_directories
|
|
setup_settings
|
|
|
|
# Fetch latest agents from GitHub (optional)
|
|
if [ "$SKIP_GIT_FETCH" = false ]; then
|
|
fetch_latest_agents
|
|
fi
|
|
|
|
install_mcp_services
|
|
install_agents
|
|
install_skills # NEW: Skills installation
|
|
install_plugins
|
|
|
|
# Verify installation
|
|
if verify_installation; then
|
|
echo ""
|
|
log_success "═══════════════════════════════════════════════════════════"
|
|
log_success "Installation completed successfully!"
|
|
log_success "═══════════════════════════════════════════════════════════"
|
|
echo ""
|
|
log_info "Summary:"
|
|
log_info " → Agents installed: $AGENTS_INSTALLED"
|
|
log_info " → Skills installed: $SKILLS_INSTALLED"
|
|
echo ""
|
|
log_info "Next steps:"
|
|
echo " 1. Restart Claude Code to load all customizations"
|
|
echo " 2. Verify agents are available in Claude Code"
|
|
echo " 3. Verify skills are available (check: ~/.claude/skills/)"
|
|
echo " 4. Test MCP tools by starting a new session"
|
|
echo ""
|
|
echo "Backup location: $BACKUP_DIR"
|
|
echo ""
|
|
echo "Sync agents later: ~/.claude/sync-agents.sh"
|
|
echo ""
|
|
else
|
|
log_error "Installation failed. Please check the errors above."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|