skill-auditor
Claude Skill Auditor & Central Repository Manager
Overview
Two responsibilities:
- Audit — Analyze SKILL.md bundles: extract metadata, detect overlap, produce cleanup plans with merge proposals.
- Central Repo — Manage a central skills repository (
$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.
When to Use
Audit Triggers
- User pastes multiple SKILL.md files and asks for analysis
- User wants to find duplicate or overlapping skills
- User wants a consolidation or cleanup plan for their skill library
- User asks which skills to merge, archive, or delete
Central Repository Triggers
- User wants to set up a central skills repository
- User wants to share skills across multiple projects
- User wants to migrate project-level skills into a central location
- User wants to sync new skills to existing projects
- User asks to audit which projects use which skills
- User wants to verify symlink health across projects
Part 1: Skill Audit
Parsing Rules
Split input into skills using the strongest available delimiter:
=== SKILL: <name> ===(preferred)# SKILL: <name>or## SKILL: <name>- If boundaries are ambiguous → create an
UNSURE_BOUNDARYnote; never guess
For each skill extract:
skill_name— from delimiter; if missing, useUnnamed Skill NNand 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 risk
Output Order
A) Per-Skill Extraction
Compact structured list (Markdown bullets or JSON) with all fields above plus uncertainty_notes.
B) Consolidation Table
| 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
C) Merge Candidates (high overlap only)
For each group:
- Proposed consolidated skill name
- 1–2 sentence description
- Core instructions as bullets
- What to deprecate and why
- Migration notes (content from old skills that must be preserved)
D) Prioritized Cleanup Checklist (10–15 items)
- Quick wins first: duplicates, obvious merges, dead skills
- Rewrites: vague descriptions, missing tool constraints
- Governance: naming conventions, category taxonomy, templates
Overlap Scoring Rubric
| 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
Part 2: Central Skills Repository
Environment
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.
Step 1: Initialize Central Repository
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
Step 2: Scan & Migrate Existing Skills
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"
}
Step 3: Link Skills to a Project
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
}
Step 4: Verify Setup
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
}
Step 5: Sync New Skills to Projects
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
}
Step 6: Git Integration
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.
Step 7: Cross-Project Audit
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
}
Part 3: Troubleshooting
Broken Symlink
# 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
Skill Not Loading
- Verify SKILL.md exists:
cat .claude/skills/<name>/SKILL.md - Check symlink resolves:
ls -L .claude/skills/<name>/SKILL.md - Ensure frontmatter is valid YAML between
---markers
Category Taxonomy
- Content Transformation (translate, rewrite, summarize)
- Research & Enrichment (web research, expansion, citations)
- Document & File Ops (PDF/DOCX/XLSX generation/editing)
- Web & Automation (scraping, scheduled tasks, monitoring)
- Dev & Integration (APIs, pipelines, codegen, CI/CD)
- Creative / Media (image/video prompts, branding)
- Governance / Meta (auditing, linting, policy enforcement)
- Skill Management (repo setup, symlinks, sync, migration) ← NEW
Integrity Rules
- Never invent tool permissions or side effects
- If a skill omits tools → "Not specified" + governance risk flag
- If a delimiter is missing → label uncertain + propose fix
- Every recommendation must be justified:
- "Merge" → include concrete consolidated skill spec
- "Disable/Archive/Delete" → cite specific reason (duplicate, obsolete, too vague, risky, unused assumptions)
- Never
rm -rfsymlinked skills — this deletes the source. Useskillshare uninstallor manualrmon the symlink only.
Optional: Governance Template
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
Common Mistakes
- Analyzing before receiving the bundle (violates two-turn handshake)
- Inventing tool permissions when a skill doesn't mention them
- Recommending "merge" without providing the actual merged spec
- Using a category set that grows unbounded — keep to the 8 categories above unless a clear gap exists
- Running
rm -rfon a symlink target instead of removing the symlink - Forgetting to run sync after making changes
MANDATORY: Final Sync
Every 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:
- Personal global skills (
~/.claude/skills/) load for ALL projects automatically — no symlinks needed - Project skills (
.claude/skills/) only load for that project — use symlinks to share skillshare synchandles distributing from source of truth to all targets- If
skillshareis not installed, warn the user and provide fallback manual sync guidance
More from haha0815/claude-meta-skills
find-skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
44skills-updater
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.
11ideation
Unified ideation skill with three modes: Quick (SCAMPER, Six Thinking Hats via Gemini API), Collaborative (dialogue-based design exploration before implementation), and Formal Review (multi-agent structured design review for high-stakes decisions). You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior.
9skillshare
|
9