Files
claude-code-glm-suite/extra-tools/install-claude-customizations.sh
uroma fcd0e4a382 feat: Update extra-tools installer with all features from main installer
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>
2026-01-16 15:11:50 +00:00

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 "$@"