Add check-skills: verify skill symlinks match source repo
Compares installed skill symlinks against the source directory, reporting missing, stale, and orphan entries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
119
scripts/check-skills
Executable file
119
scripts/check-skills
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Check which skills from the source repo are missing from the active Claude profile.
|
||||
|
||||
DEFAULT_SKILLS_REPO="$HOME/dev/claude/projects/custom-claude-skills/skills"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: check-skills [OPTIONS] [SKILLS_REPO]
|
||||
|
||||
Check which skills from the custom-claude-skills repository are missing
|
||||
from the active Claude Code profile's skills directory.
|
||||
|
||||
Arguments:
|
||||
SKILLS_REPO Path to skills source directory
|
||||
(default: ~/dev/claude/projects/custom-claude-skills/skills)
|
||||
|
||||
Options:
|
||||
--profile DIR Override Claude profile directory
|
||||
(default: $CLAUDE_CONFIG_DIR or ~/.claude)
|
||||
--dryrun, -n Accepted for convention compliance (script is read-only)
|
||||
--help, -h Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
# Colours
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
RED='\033[0;31m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Parse args
|
||||
profile_dir=""
|
||||
skills_repo=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile) profile_dir="$2"; shift 2 ;;
|
||||
--dryrun|-n) shift ;;
|
||||
--help|-h) usage; exit 0 ;;
|
||||
-*) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;;
|
||||
*) skills_repo="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
skills_repo="${skills_repo:-$DEFAULT_SKILLS_REPO}"
|
||||
profile_dir="${profile_dir:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}"
|
||||
profile_skills="$profile_dir/skills"
|
||||
|
||||
# Validate source
|
||||
if [[ ! -d "$skills_repo" ]]; then
|
||||
echo -e "${RED}ERROR${NC} Skills source directory not found: $skills_repo" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display paths (use ~ shorthand for readability)
|
||||
display_profile="${profile_skills/#$HOME/~}"
|
||||
display_source="${skills_repo/#$HOME/~}"
|
||||
echo -e "${BOLD}Profile:${NC} $display_profile"
|
||||
echo -e "${BOLD}Source:${NC} $display_source"
|
||||
echo ""
|
||||
|
||||
linked=0
|
||||
missing=0
|
||||
stale=0
|
||||
orphan=0
|
||||
|
||||
# Check each source skill
|
||||
for skill_dir in "$skills_repo"/*/; do
|
||||
[[ -d "$skill_dir" ]] || continue
|
||||
[[ -f "$skill_dir/SKILL.md" ]] || continue
|
||||
|
||||
skill_name="$(basename "$skill_dir")"
|
||||
target="$profile_skills/$skill_name"
|
||||
|
||||
if [[ -L "$target" ]]; then
|
||||
actual="$(readlink -f "$target" 2>/dev/null || echo "BROKEN")"
|
||||
expected="$(readlink -f "$skill_dir")"
|
||||
if [[ "$actual" == "$expected" ]]; then
|
||||
echo -e " ${GREEN}LINKED${NC} $skill_name"
|
||||
linked=$((linked + 1))
|
||||
else
|
||||
echo -e " ${YELLOW}STALE${NC} $skill_name (points to $actual)"
|
||||
stale=$((stale + 1))
|
||||
fi
|
||||
elif [[ -e "$target" ]]; then
|
||||
echo -e " ${YELLOW}STALE${NC} $skill_name (non-symlink exists)"
|
||||
stale=$((stale + 1))
|
||||
else
|
||||
echo -e " ${YELLOW}MISSING${NC} $skill_name"
|
||||
missing=$((missing + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for orphans in profile
|
||||
if [[ -d "$profile_skills" ]]; then
|
||||
for entry in "$profile_skills"/*/; do
|
||||
[[ -d "$entry" || -L "$entry" ]] || continue
|
||||
entry_name="$(basename "$entry")"
|
||||
if [[ ! -d "$skills_repo/$entry_name" ]]; then
|
||||
echo -e " ${CYAN}ORPHAN${NC} $entry_name (not in source repo)"
|
||||
orphan=$((orphan + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "Summary: ${GREEN}$linked linked${NC}, ${YELLOW}$missing missing${NC}, ${YELLOW}$stale stale${NC}, ${CYAN}$orphan orphan${NC}"
|
||||
|
||||
if [[ $missing -gt 0 || $stale -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "Run 'install.sh' from the custom-claude-skills repo to fix missing/stale skills."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user