diff --git a/scripts/install.sh b/scripts/install.sh index 7ad9723..738254a 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,52 +1,83 @@ #!/usr/bin/env bash set -euo pipefail -# Symlink all skills from this repo into the active Claude profile's skills/ -# directory so they're available across all Claude Code projects. +# Symlink all skills from this repo into Claude profile skill directories. # -# Uses CLAUDE_CONFIG_DIR if set (active profile), otherwise falls back to ~/.claude. +# Default: installs into the active profile (CLAUDE_CONFIG_DIR or ~/.claude). +# --all-profiles: installs into every ~/.claude and ~/.claude-* profile found. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(dirname "$SCRIPT_DIR")" SKILLS_SRC="$REPO_DIR/skills" -SKILLS_DST="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills" GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' -mkdir -p "$SKILLS_DST" - -installed=0 -skipped=0 - -for skill_dir in "$SKILLS_SRC"/*/; do - [ -d "$skill_dir" ] || continue - skill_name="$(basename "$skill_dir")" - target="$SKILLS_DST/$skill_name" - - if [ -L "$target" ]; then - existing="$(readlink -f "$target")" - expected="$(readlink -f "$skill_dir")" - if [ "$existing" = "$expected" ]; then - echo -e "${YELLOW}SKIP${NC} $skill_name (already linked)" - skipped=$((skipped + 1)) - continue - else - echo -e "${YELLOW}UPDATE${NC} $skill_name (repointing symlink)" - rm "$target" - fi - elif [ -e "$target" ]; then - echo -e "${YELLOW}SKIP${NC} $skill_name (non-symlink exists at $target — remove manually to update)" - skipped=$((skipped + 1)) - continue - fi - - ln -s "$skill_dir" "$target" - echo -e "${GREEN}INSTALLED${NC} $skill_name → $target" - installed=$((installed + 1)) +ALL_PROFILES=0 +for arg in "$@"; do + [[ "$arg" == "--all-profiles" ]] && ALL_PROFILES=1 done -echo "" -echo "Done. Installed: $installed, Skipped: $skipped" -echo "Skills are now available as slash commands in Claude Code (e.g. /reflect M8)" +# Build target list +declare -a TARGET_DIRS=() +if (( ALL_PROFILES )); then + # Active profile first, then all others + [[ -d "$HOME/.claude" ]] && TARGET_DIRS+=("$HOME/.claude") + for d in "$HOME"/.claude-*/; do + [[ -d "$d" ]] || continue + # Skip backup/json files that match the glob + [[ "$d" == *.json/ || "$d" == *.backup/ ]] && continue + TARGET_DIRS+=("${d%/}") + done +else + TARGET_DIRS=("${CLAUDE_CONFIG_DIR:-$HOME/.claude}") +fi + +total_installed=0 +total_skipped=0 + +install_to() { + local skills_dst="$1/skills" + mkdir -p "$skills_dst" + local installed=0 skipped=0 + + for skill_dir in "$SKILLS_SRC"/*/; do + [ -d "$skill_dir" ] || continue + skill_name="$(basename "$skill_dir")" + target="$skills_dst/$skill_name" + + if [ -L "$target" ]; then + existing="$(readlink -f "$target")" + expected="$(readlink -f "$skill_dir")" + if [ "$existing" = "$expected" ]; then + skipped=$((skipped + 1)) + continue + else + echo -e " ${YELLOW}UPDATE${NC} $skill_name" + rm "$target" + fi + elif [ -e "$target" ]; then + echo -e " ${YELLOW}SKIP${NC} $skill_name (non-symlink — remove manually to update)" + skipped=$((skipped + 1)) + continue + fi + + ln -s "$skill_dir" "$target" + echo -e " ${GREEN}INSTALLED${NC} $skill_name" + installed=$((installed + 1)) + done + + total_installed=$((total_installed + installed)) + total_skipped=$((total_skipped + skipped)) + echo " → $installed installed, $skipped already up to date" +} + +for profile_dir in "${TARGET_DIRS[@]}"; do + echo "Profile: $profile_dir" + install_to "$profile_dir" + echo "" +done + +echo "Done. Total installed: $total_installed, skipped: $total_skipped" +echo "Skills are available as slash commands in Claude Code (e.g. /reflect M8)"