feat: add --all-profiles flag to install.sh
Loops over ~/.claude and all ~/.claude-* directories, installing skills into each. Default (no flag) retains the existing behaviour of installing only into the active profile.
This commit is contained in:
@@ -1,52 +1,83 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Symlink all skills from this repo into the active Claude profile's skills/
|
# Symlink all skills from this repo into Claude profile skill directories.
|
||||||
# directory so they're available across all Claude Code projects.
|
|
||||||
#
|
#
|
||||||
# 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)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
SKILLS_SRC="$REPO_DIR/skills"
|
SKILLS_SRC="$REPO_DIR/skills"
|
||||||
SKILLS_DST="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills"
|
|
||||||
|
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
mkdir -p "$SKILLS_DST"
|
ALL_PROFILES=0
|
||||||
|
for arg in "$@"; do
|
||||||
installed=0
|
[[ "$arg" == "--all-profiles" ]] && ALL_PROFILES=1
|
||||||
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))
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
# Build target list
|
||||||
echo "Done. Installed: $installed, Skipped: $skipped"
|
declare -a TARGET_DIRS=()
|
||||||
echo "Skills are now available as slash commands in Claude Code (e.g. /reflect M8)"
|
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)"
|
||||||
|
|||||||
Reference in New Issue
Block a user