.cursor/skills/skill-auditor/SKILL.md
Use when auditing a collection of SKILL.md files for overlap, redundancy, or governance issues. Also use for managing a central skills repository, creating symlinks across projects, migrating skills, and syncing. Triggers when user pastes a bundle of skills, wants structured metadata extraction, consolidation recommendations, merge proposals, cleanup plans, or needs to set up/sync a central skills repo.
npx skillsauth add jinyannan/learn-claude-demo skill-auditorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Two responsibilities:
$HOME/.claude-skills-repo), symlink skills into projects, migrate scattered skills, and keep everything in sync.Two-turn protocol (audit mode): On the first message describing an audit task, confirm understanding and request the skill bundle. Do not analyze until the bundle is provided.
MANDATORY: Every operation ends with skillshare sync to distribute changes across all AI tool targets.
Split input into skills using the strongest available delimiter:
=== SKILL: <name> === (preferred)# SKILL: <name> or ## SKILL: <name>UNSURE_BOUNDARY note; never guessFor each skill extract:
skill_name — from delimiter; if missing, use Unnamed Skill NN and flag as uncertainshort_description — 1–2 sentencesmain_category — from taxonomy belownotable_allowed_tools / hooks / side_effects — tool whitelists, file writes, APIs, memory writes, external sends; if not specified → mark as "Not specified" and flag as governance riskCompact structured list (Markdown bullets or JSON) with all fields above plus uncertainty_notes.
| skill_name | main_category | similar_skills | overlap_level | recommended_action | rationale |
overlap_level: low / medium / high (see rubric below) recommended_action: keep / merge / disable / archive / delete
For each group:
| Level | Criteria | |-------|----------| | High | Same purpose, similar steps, same tools/hook patterns — mostly duplicate | | Medium | Same domain but different workflows or constraints | | Low | Loosely related; minimal shared intent |
Overlap indicators: same trigger/goal verbs · same inputs/outputs · same tools or side effects · similar examples or templates
SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
Use $CLAUDE_SKILLS_REPO env var if set, otherwise default to $HOME/.claude-skills-repo. This allows team members to use different paths.
Run when the central repo doesn't exist yet:
SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
if [ ! -d "$SKILLS_REPO" ]; then
mkdir -p "$SKILLS_REPO"
cd "$SKILLS_REPO"
git init
cat > README.md << 'HEREDOC'
# Central Claude Skills Repository
Single source of truth for reusable Claude skills.
Each subdirectory contains a skill with its SKILL.md and supporting files.
## Structure
- `<skill-name>/SKILL.md` — one directory per skill
- Projects symlink to skills they need from here
- Changes here propagate instantly to all linked projects
- Use `$CLAUDE_SKILLS_REPO` env var to override the default path
HEREDOC
git add -A && git commit -m "Initialize central skills repository"
echo "Central repo created at $SKILLS_REPO"
else
echo "Central repo already exists at $SKILLS_REPO"
fi
First, scan for all project-level skills:
SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
echo "=== Scanning for project-level skills ==="
find ~/ -path "*/.claude/skills/*/SKILL.md" \
-not -path "*/.claude-skills-repo/*" \
-not -path "*/node_modules/*" \
2>/dev/null | while read skillfile; do
skill_dir=$(dirname "$skillfile")
skill_name=$(basename "$skill_dir")
project_dir=$(echo "$skill_dir" | sed 's|/.claude/skills/.*||')
# Check if it's already a symlink
if [ -L "$skill_dir" ]; then
target=$(readlink "$skill_dir")
echo " LINKED: $skill_name ($project_dir) -> $target"
else
echo " LOCAL: $skill_name ($project_dir)"
fi
done
To migrate a specific skill:
migrate_skill() {
local SKILL_NAME="$1"
local SOURCE_PROJECT="$2"
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
local SOURCE="$SOURCE_PROJECT/.claude/skills/$SKILL_NAME"
if [ ! -d "$SOURCE" ]; then
echo "ERROR: $SOURCE does not exist"
return 1
fi
if [ -L "$SOURCE" ]; then
echo "SKIP: $SKILL_NAME is already a symlink"
return 0
fi
if [ -d "$SKILLS_REPO/$SKILL_NAME" ]; then
echo "WARNING: $SKILL_NAME already exists in central repo"
echo " Central: $(head -5 "$SKILLS_REPO/$SKILL_NAME/SKILL.md")"
echo " Local: $(head -5 "$SOURCE/SKILL.md")"
echo " Skipping — resolve manually (diff the two versions)"
return 1
fi
# Copy to central repo
cp -r "$SOURCE" "$SKILLS_REPO/$SKILL_NAME"
# Remove original and create symlink
rm -rf "$SOURCE"
ln -s "$SKILLS_REPO/$SKILL_NAME" "$SOURCE"
echo "MIGRATED: $SKILL_NAME -> $SKILLS_REPO/$SKILL_NAME"
ls -la "$SOURCE"
}
link_skills() {
local PROJECT_DIR="$1"
local MODE="${2:-all}" # "all" or skill name
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
mkdir -p "$PROJECT_DIR/.claude/skills"
if [ "$MODE" = "all" ]; then
# Link ALL skills
for skill_dir in "$SKILLS_REPO"/*/; do
local skill_name=$(basename "$skill_dir")
[ -f "$skill_dir/SKILL.md" ] || continue
[ "$skill_name" = ".git" ] && continue
if [ -L "$PROJECT_DIR/.claude/skills/$skill_name" ]; then
echo " SKIP: $skill_name (already linked)"
continue
fi
ln -s "$SKILLS_REPO/$skill_name" "$PROJECT_DIR/.claude/skills/$skill_name"
echo " LINKED: $skill_name"
done
else
# Link single skill
if [ ! -d "$SKILLS_REPO/$MODE" ]; then
echo "ERROR: Skill '$MODE' not found in central repo"
return 1
fi
ln -s "$SKILLS_REPO/$MODE" "$PROJECT_DIR/.claude/skills/$MODE"
echo " LINKED: $MODE"
fi
}
Link by tag (requires .tags file in skill directory):
link_by_tag() {
local PROJECT_DIR="$1"
local TAG="$2"
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
mkdir -p "$PROJECT_DIR/.claude/skills"
for skill_dir in "$SKILLS_REPO"/*/; do
[ -f "$skill_dir/.tags" ] || continue
if grep -q "$TAG" "$skill_dir/.tags"; then
local skill_name=$(basename "$skill_dir")
[ -L "$PROJECT_DIR/.claude/skills/$skill_name" ] && continue
ln -s "$skill_dir" "$PROJECT_DIR/.claude/skills/$skill_name"
echo " LINKED (tag=$TAG): $skill_name"
fi
done
}
verify_project() {
local PROJECT_DIR="${1:-$(pwd)}"
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
local ok=0 broken=0 local_count=0
echo "=== Symlinked Skills ($PROJECT_DIR) ==="
for entry in "$PROJECT_DIR/.claude/skills"/*/; do
local name=$(basename "${entry%/}")
if [ -L "${entry%/}" ]; then
local target=$(readlink "${entry%/}")
if [ -f "$target/SKILL.md" ]; then
echo " OK: $name -> $target"
((ok++))
else
echo " BROKEN: $name -> $target (SKILL.md missing!)"
((broken++))
fi
elif [ -d "$entry" ]; then
echo " LOCAL: $name (not symlinked)"
((local_count++))
fi
done
echo ""
echo "=== Available in Central Repo (not linked) ==="
for skill_dir in "$SKILLS_REPO"/*/; do
local skill_name=$(basename "$skill_dir")
[ -f "$skill_dir/SKILL.md" ] || continue
[ "$skill_name" = ".git" ] && continue
if [ ! -L "$PROJECT_DIR/.claude/skills/$skill_name" ] && \
[ ! -d "$PROJECT_DIR/.claude/skills/$skill_name" ]; then
local desc=$(sed -n '/^description:/s/^description: *//p' "$skill_dir/SKILL.md" 2>/dev/null | head -1)
echo " AVAILABLE: $skill_name — $desc"
fi
done
echo ""
echo "Summary: $ok linked, $broken broken, $local_count local-only"
if [ "$broken" -gt 0 ]; then
echo ""
echo "Fix broken symlinks:"
echo " find \"$PROJECT_DIR/.claude/skills/\" -type l ! -exec test -e {} \\; -print"
fi
}
After adding new skills to the central repo, detect what's new:
sync_new_skills() {
local PROJECT_DIR="${1:-$(pwd)}"
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
local new_count=0
echo "=== New skills available for $PROJECT_DIR ==="
for skill_dir in "$SKILLS_REPO"/*/; do
local skill_name=$(basename "$skill_dir")
[ -f "$skill_dir/SKILL.md" ] || continue
[ "$skill_name" = ".git" ] && continue
if [ ! -L "$PROJECT_DIR/.claude/skills/$skill_name" ] && \
[ ! -d "$PROJECT_DIR/.claude/skills/$skill_name" ]; then
local desc=$(sed -n '/^description:/s/^description: *//p' "$skill_dir/SKILL.md" 2>/dev/null | head -1)
echo " NEW: $skill_name"
[ -n "$desc" ] && echo " $desc"
((new_count++))
fi
done
if [ "$new_count" -eq 0 ]; then
echo " All central repo skills are already linked."
else
echo ""
echo "$new_count new skill(s) available. Link with:"
echo " ln -s \"\$SKILLS_REPO/<name>\" \"$PROJECT_DIR/.claude/skills/<name>\""
fi
}
commit_central_repo() {
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
cd "$SKILLS_REPO"
git add -A
if ! git diff --cached --quiet; then
git commit -m "Update skills: $(date +%Y-%m-%d)"
echo "Central repo committed."
else
echo "Central repo: no changes to commit."
fi
}
In project repos, symlinks are committed as-is — collaborators need the same $CLAUDE_SKILLS_REPO path or the env var set.
List all projects using a specific skill:
audit_skill_usage() {
local SKILL_NAME="$1"
local SKILLS_REPO="${CLAUDE_SKILLS_REPO:-$HOME/.claude-skills-repo}"
echo "=== Projects using '$SKILL_NAME' ==="
find ~/ -lname "*/.claude-skills-repo/$SKILL_NAME" 2>/dev/null | while read link; do
local project=$(echo "$link" | sed 's|/.claude/skills/.*||')
echo " $project"
done
}
# Find all broken symlinks
find .claude/skills/ -type l ! -exec test -e {} \; -print
# Fix: remove and recreate
rm .claude/skills/broken-skill
ln -s "$HOME/.claude-skills-repo/broken-skill" .claude/skills/broken-skill
cat .claude/skills/<name>/SKILL.mdls -L .claude/skills/<name>/SKILL.md--- markersrm -rf symlinked skills — this deletes the source. Use skillshare uninstall or manual rm on the symlink only.If the skill set is messy, propose a standardized SKILL.md template:
---
name: skill-name
version: 1.0.0
owner: <team/person>
category: <from taxonomy>
description: Use when...
---
# Skill Name
## Triggers
## Inputs / Outputs
## Allowed Tools & Side Effects
## Safety Constraints
## Examples
## Acceptance Criteria
rm -rf on a symlink target instead of removing the symlinkEvery operation performed by this skill MUST end with a skillshare sync command.
After any audit, migration, linking, verification, or repo change:
echo ""
echo "=== Running final skillshare sync ==="
skillshare sync
echo "=== Sync complete ==="
This ensures all changes are distributed across all configured AI tool targets (Claude, Cursor, Windsurf, etc.). Never skip this step.
Notes on sync:
~/.claude/skills/) load for ALL projects automatically — no symlinks needed.claude/skills/) only load for that project — use symlinks to shareskillshare sync handles distributing from source of truth to all targetsskillshare is not installed, warn the user and provide fallback manual sync guidancetools
Syncs skills across AI CLI tools (Claude, Cursor, Windsurf, etc.) from a single source of truth. Global mode (~/.config/skillshare/) and project mode (.skillshare/ per-repo). Commands: status, sync, install, uninstall, update, check, search, new, collect, push, pull, diff, list, doctor, audit, init-rules, trash, log, backup, restore, target, ui, upgrade. Features: target-level skill filtering (include/exclude), skill-level targets field, XDG Base Directory support, fuzzy subdirectory resolution for monorepo installs, .skillignore for repo-level skill filtering, --exclude flag, license display, multi-skill and group uninstall (--group/-G), declarative skill manifest (global + project), group field for organized placement, 49+ supported targets. Use when: managing skills across AI tools, "skillshare" CLI, skill sync/install/search, project skills setup, target filtering, security audit, web dashboard, or troubleshooting.
tools
Check and update installed Claude Code skills from multiple sources (Claude plugins and npx skills). Scans for available updates, supports batch or individual updates with intelligent local change merging, and recommends popular skills from skillsmp.com and skills.sh marketplaces. Use when users want to update skills, check for new versions, discover trending skills, or manage their skill collection.
tools
Guide for creating effective skills. Use when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
development
Use when auditing a collection of SKILL.md files for overlap, redundancy, or governance issues. Also use for managing a central skills repository, creating symlinks across projects, migrating skills, and syncing. Triggers when user pastes a bundle of skills, wants structured metadata extraction, consolidation recommendations, merge proposals, cleanup plans, or needs to set up/sync a central skills repo.