skills-collection-manager
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSkills Collection Manager
技能集合管理器
Efficiently manage, organize, and maintain large collections of Claude Code skills at scale.
可高效大规模管理、组织和维护大型Claude Code技能集合。
Overview
概述
As skill collections grow to hundreds of entries, manual management becomes impractical. This skill provides automated tools and workflows for:
- Bulk downloading skills from GitHub repositories
- Organizing skills into logical categories
- Detecting and removing duplicates
- Consolidating similar skills
- Maintaining repository health
- Generating documentation and indexes
当技能集合增长到数百条时,手动管理就变得不切实际。本技能提供以下自动化工具和工作流:
- 从GitHub仓库批量下载技能
- 将技能整理到逻辑分类中
- 检测并删除重复项
- 合并同类技能
- 维护仓库健康
- 生成文档和索引
When to Use
适用场景
Use this skill when:
- Managing 50+ skills in a collection
- Importing skills from multiple GitHub repositories
- Organizing an unstructured skill directory
- Identifying duplicate or redundant skills
- Creating team-wide skill libraries
- Maintaining organizational skill repositories
- Building curated skill collections
- Auditing skill quality and coverage
当你遇到以下情况时可使用本技能:
- 管理超过50个技能的集合
- 从多个GitHub仓库导入技能
- 整理非结构化的技能目录
- 识别重复或冗余的技能
- 创建团队级技能库
- 维护组织级技能仓库
- 构建精选技能集合
- 审计技能质量和覆盖范围
Directory Structure Patterns
目录结构模式
Pattern 1: Flat Structure
模式1:扁平化结构
skills/
├── docker-helper/
│ └── SKILL.md
├── kubernetes-deploy/
│ └── SKILL.md
├── postgres-optimization/
│ └── SKILL.md
└── ...Pros: Simple, easy to navigate
Cons: Hard to manage at scale (100+ skills)
skills/
├── docker-helper/
│ └── SKILL.md
├── kubernetes-deploy/
│ └── SKILL.md
├── postgres-optimization/
│ └── SKILL.md
└── ...优点:简单,易于导航
缺点:规模大时(100+技能)难以管理
Pattern 2: Categorized Structure
模式2:分类结构
skills/
├── automation/
│ ├── skill-harvester/
│ │ └── SKILL.md
│ └── workflow-automation/
│ └── SKILL.md
├── backend/
│ ├── api-design/
│ │ └── SKILL.md
│ └── database-optimization/
│ └── SKILL.md
├── devops/
│ ├── docker-optimization/
│ │ └── SKILL.md
│ └── kubernetes-deploy/
│ └── SKILL.md
└── ...Pros: Organized, scalable
Cons: Requires categorization logic
skills/
├── automation/
│ ├── skill-harvester/
│ │ └── SKILL.md
│ └── workflow-automation/
│ └── SKILL.md
├── backend/
│ ├── api-design/
│ │ └── SKILL.md
│ └── database-optimization/
│ └── SKILL.md
├── devops/
│ ├── docker-optimization/
│ │ └── SKILL.md
│ └── kubernetes-deploy/
│ └── SKILL.md
└── ...优点:结构清晰,可扩展
缺点:需要分类逻辑支撑
Pattern 3: Hybrid Structure
模式3:混合结构
skills/ # Flat for easy access
skills-by-category/ # Organized for browsing
duplicates/ # Quarantine area
archived/ # Old/deprecated skillsPros: Best of both worlds
Cons: More complex to maintain
skills/ # 扁平化结构便于快速访问
skills-by-category/ # 分类结构便于浏览
duplicates/ # 重复项隔离区
archived/ # 旧/已弃用技能优点:兼具前两种模式的优势
缺点:维护复杂度更高
Bulk Skill Download
技能批量下载
Download from GitHub Repository
从GitHub仓库下载
bash
#!/bin/bashbash
#!/bin/bashbulk-download-skills.sh - Download skills from GitHub repos
bulk-download-skills.sh - Download skills from GitHub repos
REPOS_FILE="${1:-repos.txt}"
OUTPUT_DIR="downloaded-skills"
CHECKPOINT="download-checkpoint.txt"
REPOS_FILE="${1:-repos.txt}"
OUTPUT_DIR="downloaded-skills"
CHECKPOINT="download-checkpoint.txt"
Create repos list if it doesn't exist
Create repos list if it doesn't exist
if [ ! -f "$REPOS_FILE" ]; then
cat > "$REPOS_FILE" << EOF
https://github.com/anthropics/claude-code-skills
https://github.com/user/custom-skills
https://github.com/team/shared-skills
EOF
echo "Created example $REPOS_FILE - edit and run again"
exit 0
fi
mkdir -p "$OUTPUT_DIR"
if [ ! -f "$REPOS_FILE" ]; then
cat > "$REPOS_FILE" << EOF
https://github.com/anthropics/claude-code-skills
https://github.com/user/custom-skills
https://github.com/team/shared-skills
EOF
echo "Created example $REPOS_FILE - edit and run again"
exit 0
fi
mkdir -p "$OUTPUT_DIR"
Process repos in batches
Process repos in batches
while read -r repo_url; do
# Skip comments and empty lines
[[ "$repo_url" =~ ^# ]] && continue
[[ -z "$repo_url" ]] && continue
# Check if already downloaded
if grep -q "$repo_url" "$CHECKPOINT" 2>/dev/null; then
echo "✓ Skipping $repo_url (already downloaded)"
continue
fi
echo "=== Downloading: $repo_url ==="
# Extract repo name
REPO_NAME=$(basename "$repo_url" .git)
TEMP_DIR=$(mktemp -d)
# Clone with timeout
if timeout 60s git clone --depth 1 "$repo_url" "$TEMP_DIR" 2>/dev/null; then
# Find and copy skill files
SKILLS_FOUND=0
# Look for skills in common locations
for PATTERN in "skills/*/SKILL.md" "skills/**/skill.md" ".claude/skills/*/SKILL.md"; do
find "$TEMP_DIR" -path "*/$PATTERN" 2>/dev/null | while read skill_file; do
# Extract skill name (parent directory)
SKILL_NAME=$(basename $(dirname "$skill_file"))
DEST_DIR="$OUTPUT_DIR/${REPO_NAME}/${SKILL_NAME}"
mkdir -p "$DEST_DIR"
cp "$skill_file" "$DEST_DIR/"
# Copy additional files if present
SKILL_DIR=$(dirname "$skill_file")
cp "$SKILL_DIR"/*.md "$DEST_DIR/" 2>/dev/null || true
cp "$SKILL_DIR"/*.yaml "$DEST_DIR/" 2>/dev/null || true
cp "$SKILL_DIR"/*.json "$DEST_DIR/" 2>/dev/null || true
SKILLS_FOUND=$((SKILLS_FOUND + 1))
echo " ✓ Copied: $SKILL_NAME"
done
done
if [ $SKILLS_FOUND -gt 0 ]; then
echo "$repo_url" >> "$CHECKPOINT"
echo "✓ Downloaded $SKILLS_FOUND skills from $REPO_NAME"
else
echo "⚠️ No skills found in $REPO_NAME"
fi
rm -rf "$TEMP_DIR"
else
echo "✗ Failed to clone $repo_url"
fi
echo ""done < "$REPOS_FILE"
while read -r repo_url; do
# Skip comments and empty lines
[[ "$repo_url" =~ ^# ]] && continue
[[ -z "$repo_url" ]] && continue
# Check if already downloaded
if grep -q "$repo_url" "$CHECKPOINT" 2>/dev/null; then
echo "✓ Skipping $repo_url (already downloaded)"
continue
fi
echo "=== Downloading: $repo_url ==="
# Extract repo name
REPO_NAME=$(basename "$repo_url" .git)
TEMP_DIR=$(mktemp -d)
# Clone with timeout
if timeout 60s git clone --depth 1 "$repo_url" "$TEMP_DIR" 2>/dev/null; then
# Find and copy skill files
SKILLS_FOUND=0
# Look for skills in common locations
for PATTERN in "skills/*/SKILL.md" "skills/**/skill.md" ".claude/skills/*/SKILL.md"; do
find "$TEMP_DIR" -path "*/$PATTERN" 2>/dev/null | while read skill_file; do
# Extract skill name (parent directory)
SKILL_NAME=$(basename $(dirname "$skill_file"))
DEST_DIR="$OUTPUT_DIR/${REPO_NAME}/${SKILL_NAME}"
mkdir -p "$DEST_DIR"
cp "$skill_file" "$DEST_DIR/"
# Copy additional files if present
SKILL_DIR=$(dirname "$skill_file")
cp "$SKILL_DIR"/*.md "$DEST_DIR/" 2>/dev/null || true
cp "$SKILL_DIR"/*.yaml "$DEST_DIR/" 2>/dev/null || true
cp "$SKILL_DIR"/*.json "$DEST_DIR/" 2>/dev/null || true
SKILLS_FOUND=$((SKILLS_FOUND + 1))
echo " ✓ Copied: $SKILL_NAME"
done
done
if [ $SKILLS_FOUND -gt 0 ]; then
echo "$repo_url" >> "$CHECKPOINT"
echo "✓ Downloaded $SKILLS_FOUND skills from $REPO_NAME"
else
echo "⚠️ No skills found in $REPO_NAME"
fi
rm -rf "$TEMP_DIR"
else
echo "✗ Failed to clone $repo_url"
fi
echo ""done < "$REPOS_FILE"
Summary
Summary
TOTAL_SKILLS=$(find "$OUTPUT_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "=== Download Complete ==="
echo "Total skills downloaded: $TOTAL_SKILLS"
echo "Output directory: $OUTPUT_DIR"
undefinedTOTAL_SKILLS=$(find "$OUTPUT_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "=== Download Complete ==="
echo "Total skills downloaded: $TOTAL_SKILLS"
echo "Output directory: $OUTPUT_DIR"
undefinedBatch Download Script
批量下载脚本
bash
#!/bin/bashbash
#!/bin/bashdownload-top-repos.sh - Download skills from popular repositories
download-top-repos.sh - Download skills from popular repositories
Top Claude Code skill repositories
Top Claude Code skill repositories
REPOS=(
"https://github.com/anthropics/claude-code-skills"
"https://github.com/works/claude-code-skills"
"https://github.com/jonbaker99/my-claude-code-skills"
"https://github.com/diet103/my_claude_skills"
"https://github.com/mrgoonie/my-claude-code-skills"
)
BATCH_SIZE=5
PROCESSED=0
for repo in "${REPOS[@]}"; do
echo "$repo" >> repos-batch.txt
PROCESSED=$((PROCESSED + 1))
# Process in batches to avoid timeouts
if [ $((PROCESSED % BATCH_SIZE)) -eq 0 ]; then
./bulk-download-skills.sh repos-batch.txt
rm repos-batch.txt
echo "Batch complete. Continuing..."
sleep 2
fidone
REPOS=(
"https://github.com/anthropics/claude-code-skills"
"https://github.com/works/claude-code-skills"
"https://github.com/jonbaker99/my-claude-code-skills"
"https://github.com/diet103/my_claude_skills"
"https://github.com/mrgoonie/my-claude-code-skills"
)
BATCH_SIZE=5
PROCESSED=0
for repo in "${REPOS[@]}"; do
echo "$repo" >> repos-batch.txt
PROCESSED=$((PROCESSED + 1))
# Process in batches to avoid timeouts
if [ $((PROCESSED % BATCH_SIZE)) -eq 0 ]; then
./bulk-download-skills.sh repos-batch.txt
rm repos-batch.txt
echo "Batch complete. Continuing..."
sleep 2
fidone
Process remaining
Process remaining
if [ -f repos-batch.txt ]; then
./bulk-download-skills.sh repos-batch.txt
rm repos-batch.txt
fi
undefinedif [ -f repos-batch.txt ]; then
./bulk-download-skills.sh repos-batch.txt
rm repos-batch.txt
fi
undefinedSkill Organization
技能分类整理
Auto-Categorization
自动分类
bash
#!/bin/bashbash
#!/bin/bashcategorize-skills.sh - Auto-categorize skills based on content
categorize-skills.sh - Auto-categorize skills based on content
SKILLS_DIR="${1:-skills}"
OUTPUT_DIR="skills-by-category"
SKILLS_DIR="${1:-skills}"
OUTPUT_DIR="skills-by-category"
Category mapping based on keywords
Category mapping based on keywords
declare -A CATEGORIES=(
["docker|container|kubernetes|k8s"]="infrastructure"
["api|endpoint|rest|graphql|backend"]="backend"
["react|vue|angular|frontend|ui|component"]="frontend"
["test|testing|jest|pytest|mocha"]="testing"
["ci|cd|deploy|github.action|jenkins"]="devops"
["database|postgres|mysql|mongodb|sql"]="databases"
["auth|authentication|jwt|oauth|security"]="security"
["aws|azure|gcp|cloud|serverless"]="cloud"
["python|javascript|typescript|golang|rust"]="development"
["doc|documentation|readme|markdown"]="documentation"
)
mkdir -p "$OUTPUT_DIR"
declare -A CATEGORIES=(
["docker|container|kubernetes|k8s"]="infrastructure"
["api|endpoint|rest|graphql|backend"]="backend"
["react|vue|angular|frontend|ui|component"]="frontend"
["test|testing|jest|pytest|mocha"]="testing"
["ci|cd|deploy|github.action|jenkins"]="devops"
["database|postgres|mysql|mongodb|sql"]="databases"
["auth|authentication|jwt|oauth|security"]="security"
["aws|azure|gcp|cloud|serverless"]="cloud"
["python|javascript|typescript|golang|rust"]="development"
["doc|documentation|readme|markdown"]="documentation"
)
mkdir -p "$OUTPUT_DIR"
Process each skill
Process each skill
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
SKILL_CONTENT=$(cat "$skill_file" | tr '[:upper:]' '[:lower:]')
echo "Processing: $SKILL_NAME"
# Try to match category
MATCHED_CATEGORY=""
for pattern in "${!CATEGORIES[@]}"; do
if echo "$SKILL_CONTENT" | grep -qE "$pattern"; then
MATCHED_CATEGORY="${CATEGORIES[$pattern]}"
break
fi
done
# Default category if no match
if [ -z "$MATCHED_CATEGORY" ]; then
MATCHED_CATEGORY="uncategorized"
fi
# Copy to categorized directory
DEST_DIR="$OUTPUT_DIR/$MATCHED_CATEGORY/$SKILL_NAME"
mkdir -p "$DEST_DIR"
cp -r "$(dirname $skill_file)"/* "$DEST_DIR/"
echo " → $MATCHED_CATEGORY"done
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
SKILL_CONTENT=$(cat "$skill_file" | tr '[:upper:]' '[:lower:]')
echo "Processing: $SKILL_NAME"
# Try to match category
MATCHED_CATEGORY=""
for pattern in "${!CATEGORIES[@]}"; do
if echo "$SKILL_CONTENT" | grep -qE "$pattern"; then
MATCHED_CATEGORY="${CATEGORIES[$pattern]}"
break
fi
done
# Default category if no match
if [ -z "$MATCHED_CATEGORY" ]; then
MATCHED_CATEGORY="uncategorized"
fi
# Copy to categorized directory
DEST_DIR="$OUTPUT_DIR/$MATCHED_CATEGORY/$SKILL_NAME"
mkdir -p "$DEST_DIR"
cp -r "$(dirname $skill_file)"/* "$DEST_DIR/"
echo " → $MATCHED_CATEGORY"done
Generate summary
Generate summary
echo ""
echo "=== Categorization Summary ==="
for category_dir in "$OUTPUT_DIR"/*; do
CATEGORY=$(basename "$category_dir")
COUNT=$(find "$category_dir" -name "SKILL.md" -o -name "skill.md" | wc -l)
printf "%-20s : %3d skills\n" "$CATEGORY" "$COUNT"
done
undefinedecho ""
echo "=== Categorization Summary ==="
for category_dir in "$OUTPUT_DIR"/*; do
CATEGORY=$(basename "$category_dir")
COUNT=$(find "$category_dir" -name "SKILL.md" -o -name "skill.md" | wc -l)
printf "%-20s : %3d skills\n" "$CATEGORY" "$COUNT"
done
undefinedManual Reorganization
手动重组
bash
#!/bin/bashbash
#!/bin/bashreorganize-skills.sh - Interactive skill reorganization
reorganize-skills.sh - Interactive skill reorganization
SKILLS_DIR="skills"
CATEGORIES=("automation" "backend" "cloud" "data-engineering" "devops" "documentation" "frontend" "infrastructure" "security" "testing")
SKILLS_DIR="skills"
CATEGORIES=("automation" "backend" "cloud" "data-engineering" "devops" "documentation" "frontend" "infrastructure" "security" "testing")
Show uncategorized skills
Show uncategorized skills
echo "=== Uncategorized Skills ==="
find "$SKILLS_DIR" -maxdepth 1 -type d | tail -n +2 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
echo "- $SKILL_NAME"
done
echo ""
echo "Available categories:"
for i in "${!CATEGORIES[@]}"; do
echo "$((i+1))) ${CATEGORIES[$i]}"
done
echo ""
read -p "Reorganize skills? (y/n) " -n 1 -r
echo
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 0
find "$SKILLS_DIR" -maxdepth 1 -type d | tail -n +2 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
echo ""
echo "Skill: $SKILL_NAME"
echo "Description: $(grep -m 1 "description:" "$skill_dir/SKILL.md" 2>/dev/null | cut -d: -f2-)"
echo ""
read -p "Category (1-${#CATEGORIES[@]}, s=skip): " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#CATEGORIES[@]}" ]; then
CATEGORY="${CATEGORIES[$((choice-1))]}"
DEST_DIR="skills-by-category/$CATEGORY/$SKILL_NAME"
mkdir -p "$DEST_DIR"
mv "$skill_dir"/* "$DEST_DIR/"
rmdir "$skill_dir"
echo "✓ Moved to $CATEGORY"
fidone
undefinedecho "=== Uncategorized Skills ==="
find "$SKILLS_DIR" -maxdepth 1 -type d | tail -n +2 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
echo "- $SKILL_NAME"
done
echo ""
echo "Available categories:"
for i in "${!CATEGORIES[@]}"; do
echo "$((i+1))) ${CATEGORIES[$i]}"
done
echo ""
read -p "Reorganize skills? (y/n) " -n 1 -r
echo
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 0
find "$SKILLS_DIR" -maxdepth 1 -type d | tail -n +2 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
echo ""
echo "Skill: $SKILL_NAME"
echo "Description: $(grep -m 1 "description:" "$skill_dir/SKILL.md" 2>/dev/null | cut -d: -f2-)"
echo ""
read -p "Category (1-${#CATEGORIES[@]}, s=skip): " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#CATEGORIES[@]}" ]; then
CATEGORY="${CATEGORIES[$((choice-1))]}"
DEST_DIR="skills-by-category/$CATEGORY/$SKILL_NAME"
mkdir -p "$DEST_DIR"
mv "$skill_dir"/* "$DEST_DIR/"
rmdir "$skill_dir"
echo "✓ Moved to $CATEGORY"
fidone
undefinedDuplicate Detection
重复项检测
Simple Duplicate Finder
简易重复项查找器
bash
#!/bin/bashbash
#!/bin/bashfind-duplicates.sh - Find duplicate skills
find-duplicates.sh - Find duplicate skills
SKILLS_DIR="${1:-skills}"
DUPLICATES_DIR="duplicates"
mkdir -p "$DUPLICATES_DIR"
SKILLS_DIR="${1:-skills}"
DUPLICATES_DIR="duplicates"
mkdir -p "$DUPLICATES_DIR"
Create temporary index
Create temporary index
TEMP_INDEX=$(mktemp)
TEMP_INDEX=$(mktemp)
Index all skills by normalized name
Index all skills by normalized name
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_DIR=$(dirname "$skill_file")
SKILL_NAME=$(basename "$SKILL_DIR")
# Normalize name (remove variations)
NORMALIZED=$(echo "$SKILL_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[-_]//g')
echo "$NORMALIZED|$SKILL_DIR" >> "$TEMP_INDEX"done
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_DIR=$(dirname "$skill_file")
SKILL_NAME=$(basename "$SKILL_DIR")
# Normalize name (remove variations)
NORMALIZED=$(echo "$SKILL_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[-_]//g')
echo "$NORMALIZED|$SKILL_DIR" >> "$TEMP_INDEX"done
Find duplicates
Find duplicates
cat "$TEMP_INDEX" | cut -d'|' -f1 | sort | uniq -d | while read dup_name; do
echo "=== Duplicate: $dup_name ==="
grep "^$dup_name|" "$TEMP_INDEX" | cut -d'|' -f2 | while read skill_dir; do
ORIGINAL_NAME=$(basename "$skill_dir")
echo " - $ORIGINAL_NAME"
# Move to duplicates folder
DUP_DEST="$DUPLICATES_DIR/$ORIGINAL_NAME"
if [ ! -d "$DUP_DEST" ]; then
mv "$skill_dir" "$DUP_DEST"
echo " → Moved to $DUPLICATES_DIR"
fi
done
echo ""done
rm "$TEMP_INDEX"
cat "$TEMP_INDEX" | cut -d'|' -f1 | sort | uniq -d | while read dup_name; do
echo "=== Duplicate: $dup_name ==="
grep "^$dup_name|" "$TEMP_INDEX" | cut -d'|' -f2 | while read skill_dir; do
ORIGINAL_NAME=$(basename "$skill_dir")
echo " - $ORIGINAL_NAME"
# Move to duplicates folder
DUP_DEST="$DUPLICATES_DIR/$ORIGINAL_NAME"
if [ ! -d "$DUP_DEST" ]; then
mv "$skill_dir" "$DUP_DEST"
echo " → Moved to $DUPLICATES_DIR"
fi
done
echo ""done
rm "$TEMP_INDEX"
Summary
Summary
DUP_COUNT=$(find "$DUPLICATES_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "Found $DUP_COUNT potential duplicates in $DUPLICATES_DIR"
echo "Review and manually merge or delete"
undefinedDUP_COUNT=$(find "$DUPLICATES_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "Found $DUP_COUNT potential duplicates in $DUPLICATES_DIR"
echo "Review and manually merge or delete"
undefinedAdvanced Duplicate Detection (Content-based)
高级重复检测(基于内容)
python
#!/usr/bin/env python3python
#!/usr/bin/env python3detect-duplicates.py - Content-based duplicate detection
detect-duplicates.py - Content-based duplicate detection
import os
import re
from pathlib import Path
from difflib import SequenceMatcher
from collections import defaultdict
def normalize_content(content):
"""Normalize content for comparison"""
# Remove frontmatter
content = re.sub(r'^---.*?---', '', content, flags=re.DOTALL)
# Remove whitespace and lowercase
content = re.sub(r'\s+', ' ', content.lower())
return content.strip()
def similarity_ratio(content1, content2):
"""Calculate similarity ratio between two contents"""
return SequenceMatcher(None, content1, content2).ratio()
def find_duplicates(skills_dir, threshold=0.8):
"""Find skills with similar content"""
skills = {}
# Read all skills
for skill_file in Path(skills_dir).rglob('SKILL.md'):
skill_name = skill_file.parent.name
with open(skill_file, 'r', encoding='utf-8') as f:
content = normalize_content(f.read())
skills[skill_name] = {
'content': content,
'path': str(skill_file.parent)
}
# Find duplicates
duplicates = defaultdict(list)
checked = set()
for name1, data1 in skills.items():
for name2, data2 in skills.items():
if name1 == name2 or (name1, name2) in checked:
continue
ratio = similarity_ratio(data1['content'], data2['content'])
if ratio >= threshold:
duplicates[name1].append({
'name': name2,
'similarity': ratio,
'path': data2['path']
})
checked.add((name1, name2))
checked.add((name2, name1))
# Report findings
if duplicates:
print("=== Duplicate Skills Found ===\n")
for skill, dups in duplicates.items():
print(f"{skill}:")
for dup in dups:
print(f" - {dup['name']} ({dup['similarity']:.1%} similar)")
print(f" Path: {dup['path']}")
print()
print(f"\nTotal duplicate groups: {len(duplicates)}")
else:
print("No duplicates found")if name == 'main':
import sys
skills_dir = sys.argv[1] if len(sys.argv) > 1 else 'skills'
threshold = float(sys.argv[2]) if len(sys.argv) > 2 else 0.8
find_duplicates(skills_dir, threshold)undefinedimport os
import re
from pathlib import Path
from difflib import SequenceMatcher
from collections import defaultdict
def normalize_content(content):
"""Normalize content for comparison"""
# Remove frontmatter
content = re.sub(r'^---.*?---', '', content, flags=re.DOTALL)
# Remove whitespace and lowercase
content = re.sub(r'\s+', ' ', content.lower())
return content.strip()
def similarity_ratio(content1, content2):
"""Calculate similarity ratio between two contents"""
return SequenceMatcher(None, content1, content2).ratio()
def find_duplicates(skills_dir, threshold=0.8):
"""Find skills with similar content"""
skills = {}
# Read all skills
for skill_file in Path(skills_dir).rglob('SKILL.md'):
skill_name = skill_file.parent.name
with open(skill_file, 'r', encoding='utf-8') as f:
content = normalize_content(f.read())
skills[skill_name] = {
'content': content,
'path': str(skill_file.parent)
}
# Find duplicates
duplicates = defaultdict(list)
checked = set()
for name1, data1 in skills.items():
for name2, data2 in skills.items():
if name1 == name2 or (name1, name2) in checked:
continue
ratio = similarity_ratio(data1['content'], data2['content'])
if ratio >= threshold:
duplicates[name1].append({
'name': name2,
'similarity': ratio,
'path': data2['path']
})
checked.add((name1, name2))
checked.add((name2, name1))
# Report findings
if duplicates:
print("=== Duplicate Skills Found ===\n")
for skill, dups in duplicates.items():
print(f"{skill}:")
for dup in dups:
print(f" - {dup['name']} ({dup['similarity']:.1%} similar)")
print(f" Path: {dup['path']}")
print()
print(f"\nTotal duplicate groups: {len(duplicates)}")
else:
print("No duplicates found")if name == 'main':
import sys
skills_dir = sys.argv[1] if len(sys.argv) > 1 else 'skills'
threshold = float(sys.argv[2]) if len(sys.argv) > 2 else 0.8
find_duplicates(skills_dir, threshold)undefinedSkill Consolidation
技能合并
Merge Similar Skills
合并相似技能
bash
#!/bin/bashbash
#!/bin/bashconsolidate-skills.sh - Merge similar skills
consolidate-skills.sh - Merge similar skills
SKILL1_DIR="$1"
SKILL2_DIR="$2"
OUTPUT_NAME="$3"
if [ -z "$SKILL1_DIR" ] || [ -z "$SKILL2_DIR" ] || [ -z "$OUTPUT_NAME" ]; then
echo "Usage: $0 <skill1-dir> <skill2-dir> <output-name>"
exit 1
fi
OUTPUT_DIR="skills/$OUTPUT_NAME"
mkdir -p "$OUTPUT_DIR"
SKILL1_DIR="$1"
SKILL2_DIR="$2"
OUTPUT_NAME="$3"
if [ -z "$SKILL1_DIR" ] || [ -z "$SKILL2_DIR" ] || [ -z "$OUTPUT_NAME" ]; then
echo "Usage: $0 <skill1-dir> <skill2-dir> <output-name>"
exit 1
fi
OUTPUT_DIR="skills/$OUTPUT_NAME"
mkdir -p "$OUTPUT_DIR"
Extract metadata from both skills
Extract metadata from both skills
SKILL1_NAME=$(grep "^name:" "$SKILL1_DIR/SKILL.md" | cut -d: -f2 | xargs)
SKILL2_NAME=$(grep "^name:" "$SKILL2_DIR/SKILL.md" | cut -d: -f2 | xargs)
DESC1=$(grep "^description:" "$SKILL1_DIR/SKILL.md" | cut -d: -f2 | xargs)
DESC2=$(grep "^description:" "$SKILL2_DIR/SKILL.md" | cut -d: -f2 | xargs)
SKILL1_NAME=$(grep "^name:" "$SKILL1_DIR/SKILL.md" | cut -d: -f2 | xargs)
SKILL2_NAME=$(grep "^name:" "$SKILL2_DIR/SKILL.md" | cut -d: -f2 | xargs)
DESC1=$(grep "^description:" "$SKILL1_DIR/SKILL.md" | cut -d: -f2 | xargs)
DESC2=$(grep "^description:" "$SKILL2_DIR/SKILL.md" | cut -d: -f2 | xargs)
Create consolidated skill
Create consolidated skill
cat > "$OUTPUT_DIR/SKILL.md" << EOF
name: $OUTPUT_NAME
description: Consolidated skill combining $SKILL1_NAME and $SKILL2_NAME
consolidated-from:
- $SKILL1_NAME
- $SKILL2_NAME license: MIT
cat > "$OUTPUT_DIR/SKILL.md" << EOF
name: $OUTPUT_NAME
description: Consolidated skill combining $SKILL1_NAME and $SKILL2_NAME
consolidated-from:
- $SKILL1_NAME
- $SKILL2_NAME license: MIT
${OUTPUT_NAME^}
${OUTPUT_NAME^}
This skill consolidates functionality from:
- $SKILL1_NAME: $DESC1
- $SKILL2_NAME: $DESC2
This skill consolidates functionality from:
- $SKILL1_NAME: $DESC1
- $SKILL2_NAME: $DESC2
From $SKILL1_NAME
From $SKILL1_NAME
$(sed -n '/^# /,$ p' "$SKILL1_DIR/SKILL.md" | tail -n +2)
$(sed -n '/^# /,$ p' "$SKILL1_DIR/SKILL.md" | tail -n +2)
From $SKILL2_NAME
From $SKILL2_NAME
$(sed -n '/^# /,$ p' "$SKILL2_DIR/SKILL.md" | tail -n +2)
$(sed -n '/^# /,$ p' "$SKILL2_DIR/SKILL.md" | tail -n +2)
Combined Usage
Combined Usage
TODO: Add guidance on using consolidated functionality
EOF
echo "✓ Created consolidated skill: $OUTPUT_DIR"
echo "Review and edit: $OUTPUT_DIR/SKILL.md"
undefinedTODO: Add guidance on using consolidated functionality
EOF
echo "✓ Created consolidated skill: $OUTPUT_DIR"
echo "Review and edit: $OUTPUT_DIR/SKILL.md"
undefinedRepository Maintenance
仓库维护
Health Check
健康检查
bash
#!/bin/bashbash
#!/bin/bashhealth-check.sh - Check repository health
health-check.sh - Check repository health
SKILLS_DIR="${1:-skills}"
echo "=== Skills Repository Health Check ==="
echo ""
SKILLS_DIR="${1:-skills}"
echo "=== Skills Repository Health Check ==="
echo ""
Count total skills
Count total skills
TOTAL=$(find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "Total skills: $TOTAL"
echo ""
TOTAL=$(find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "Total skills: $TOTAL"
echo ""
Check for required files
Check for required files
echo "=== Missing Files ==="
MISSING=0
find "$SKILLS_DIR" -type d -mindepth 1 | while read skill_dir; do
if [ ! -f "$skill_dir/SKILL.md" ] && [ ! -f "$skill_dir/skill.md" ]; then
echo "✗ $(basename $skill_dir): No SKILL.md file"
MISSING=$((MISSING + 1))
fi
done
[ $MISSING -eq 0 ] && echo "✓ All skills have SKILL.md files"
echo ""
echo "=== Missing Files ==="
MISSING=0
find "$SKILLS_DIR" -type d -mindepth 1 | while read skill_dir; do
if [ ! -f "$skill_dir/SKILL.md" ] && [ ! -f "$skill_dir/skill.md" ]; then
echo "✗ $(basename $skill_dir): No SKILL.md file"
MISSING=$((MISSING + 1))
fi
done
[ $MISSING -eq 0 ] && echo "✓ All skills have SKILL.md files"
echo ""
Check for metadata
Check for metadata
echo "=== Missing Metadata ==="
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
# Check for required frontmatter
if ! grep -q "^name:" "$skill_file"; then
echo "✗ $SKILL_NAME: Missing 'name' in frontmatter"
fi
if ! grep -q "^description:" "$skill_file"; then
echo "✗ $SKILL_NAME: Missing 'description' in frontmatter"
fidone
echo ""
echo "=== Missing Metadata ==="
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
# Check for required frontmatter
if ! grep -q "^name:" "$skill_file"; then
echo "✗ $SKILL_NAME: Missing 'name' in frontmatter"
fi
if ! grep -q "^description:" "$skill_file"; then
echo "✗ $SKILL_NAME: Missing 'description' in frontmatter"
fidone
echo ""
Check for empty files
Check for empty files
echo "=== Empty Skills ==="
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
if [ ! -s "$skill_file" ]; then
echo "✗ $(basename $(dirname $skill_file)): Empty file"
fi
done
echo ""
echo "=== Empty Skills ==="
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | while read skill_file; do
if [ ! -s "$skill_file" ]; then
echo "✗ $(basename $(dirname $skill_file)): Empty file"
fi
done
echo ""
Check naming conventions
Check naming conventions
echo "=== Naming Convention Issues ==="
find "$SKILLS_DIR" -type d -mindepth 1 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
# Check for kebab-case
if ! echo "$SKILL_NAME" | grep -qE '^[a-z0-9]+(-[a-z0-9]+)*$'; then
echo "⚠️ $SKILL_NAME: Not in kebab-case format"
fidone
echo ""
echo "=== Health Check Complete ==="
undefinedecho "=== Naming Convention Issues ==="
find "$SKILLS_DIR" -type d -mindepth 1 | while read skill_dir; do
SKILL_NAME=$(basename "$skill_dir")
# Check for kebab-case
if ! echo "$SKILL_NAME" | grep -qE '^[a-z0-9]+(-[a-z0-9]+)*$'; then
echo "⚠️ $SKILL_NAME: Not in kebab-case format"
fidone
echo ""
echo "=== Health Check Complete ==="
undefinedGenerate Documentation
生成文档
bash
#!/bin/bashbash
#!/bin/bashgenerate-docs.sh - Generate skill collection documentation
generate-docs.sh - Generate skill collection documentation
SKILLS_DIR="${1:-skills}"
OUTPUT_FILE="SKILLS_COLLECTION_README.md"
cat > "$OUTPUT_FILE" << EOF
SKILLS_DIR="${1:-skills}"
OUTPUT_FILE="SKILLS_COLLECTION_README.md"
cat > "$OUTPUT_FILE" << EOF
Skills Collection
Skills Collection
Auto-generated documentation for skill collection.
Last Updated: $(date +"%Y-%m-%d")
Total Skills: $(find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
Auto-generated documentation for skill collection.
Last Updated: $(date +"%Y-%m-%d")
Total Skills: $(find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | wc -l)
Skills by Category
Skills by Category
EOF
EOF
Group by category (if using categorized structure)
Group by category (if using categorized structure)
if [ -d "skills-by-category" ]; then
for category_dir in skills-by-category/*; do
CATEGORY=$(basename "$category_dir")
COUNT=$(find "$category_dir" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "### ${CATEGORY^} ($COUNT)" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
find "$category_dir" -name "SKILL.md" -o -name "skill.md" | sort | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
DESC=$(grep "^description:" "$skill_file" | cut -d: -f2- | xargs)
echo "- **$SKILL_NAME**: $DESC" >> "$OUTPUT_FILE"
done
echo "" >> "$OUTPUT_FILE"
doneelse
# Flat structure
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | sort | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
DESC=$(grep "^description:" "$skill_file" | cut -d: -f2- | xargs)
echo "- **$SKILL_NAME**: $DESC" >> "$OUTPUT_FILE"
donefi
echo "✓ Generated: $OUTPUT_FILE"
undefinedif [ -d "skills-by-category" ]; then
for category_dir in skills-by-category/*; do
CATEGORY=$(basename "$category_dir")
COUNT=$(find "$category_dir" -name "SKILL.md" -o -name "skill.md" | wc -l)
echo "### ${CATEGORY^} ($COUNT)" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
find "$category_dir" -name "SKILL.md" -o -name "skill.md" | sort | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
DESC=$(grep "^description:" "$skill_file" | cut -d: -f2- | xargs)
echo "- **$SKILL_NAME**: $DESC" >> "$OUTPUT_FILE"
done
echo "" >> "$OUTPUT_FILE"
doneelse
# Flat structure
find "$SKILLS_DIR" -name "SKILL.md" -o -name "skill.md" | sort | while read skill_file; do
SKILL_NAME=$(basename $(dirname "$skill_file"))
DESC=$(grep "^description:" "$skill_file" | cut -d: -f2- | xargs)
echo "- **$SKILL_NAME**: $DESC" >> "$OUTPUT_FILE"
donefi
echo "✓ Generated: $OUTPUT_FILE"
undefinedBest Practices
最佳实践
✅ DO
✅ 推荐做法
- Categorize consistently - Use standard categories across team
- Check for duplicates regularly before adding new skills
- Maintain metadata - Ensure all skills have proper frontmatter
- Document changes - Keep CHANGELOG or version history
- Use naming conventions - kebab-case for all skill names
- Version control - Commit frequently with clear messages
- Test skills - Verify skills work before adding to collection
- Review regularly - Audit collection health monthly
- 分类保持一致 - 团队内使用统一的分类标准
- 定期检查重复项 - 新增技能前先检查是否已有重复
- 维护元数据 - 确保所有技能都有正确的前置元数据
- 记录变更 - 保留CHANGELOG或版本历史
- 遵循命名规范 - 所有技能名称使用kebab-case格式
- 使用版本控制 - 频繁提交并编写清晰的提交信息
- 测试技能 - 加入集合前验证技能可以正常工作
- 定期审核 - 每月审计一次集合的健康状态
❌ DON'T
❌ 不推荐做法
- Don't mix formats - Keep consistent SKILL.md naming
- Don't duplicate - Search before creating new skills
- Don't leave orphans - Remove skills properly (don't just delete files)
- Don't skip descriptions - Every skill needs clear description
- Don't over-categorize - Keep category tree shallow (1-2 levels)
- Don't hoard - Archive or delete truly obsolete skills
- Don't ignore errors - Fix health check issues promptly
- 不要混用格式 - 保持统一的SKILL.md命名规范
- 不要重复创建 - 新建技能前先搜索是否已有同类技能
- 不要留下孤儿文件 - 正确删除技能,不要只删除部分文件
- 不要省略描述 - 每个技能都要有清晰的描述
- 不要过度分类 - 保持分类树层级较浅(1-2层即可)
- 不要囤积无用技能 - 归档或删除完全过时的技能
- 不要忽略错误 - 及时修复健康检查发现的问题
Workflows
工作流
Weekly Maintenance
每周维护
bash
#!/bin/bashbash
#!/bin/bashweekly-maintenance.sh
weekly-maintenance.sh
echo "=== Weekly Skills Collection Maintenance ==="
echo "=== Weekly Skills Collection Maintenance ==="
1. Health check
1. Health check
./health-check.sh skills
./health-check.sh skills
2. Find duplicates
2. Find duplicates
./find-duplicates.sh skills
./find-duplicates.sh skills
3. Update documentation
3. Update documentation
./generate-docs.sh skills
./generate-docs.sh skills
4. Commit changes
4. Commit changes
git add .
git commit -m "chore: Weekly skills collection maintenance"
echo "✓ Maintenance complete"
undefinedgit add .
git commit -m "chore: Weekly skills collection maintenance"
echo "✓ Maintenance complete"
undefinedNew Skills Integration
新技能集成
bash
#!/bin/bashbash
#!/bin/bashintegrate-new-skills.sh
integrate-new-skills.sh
NEW_SKILLS_DIR="$1"
NEW_SKILLS_DIR="$1"
1. Check for duplicates against existing
1. Check for duplicates against existing
echo "Checking for duplicates..."
echo "Checking for duplicates..."
... duplicate check logic ...
... duplicate check logic ...
2. Auto-categorize
2. Auto-categorize
echo "Categorizing new skills..."
./categorize-skills.sh "$NEW_SKILLS_DIR"
echo "Categorizing new skills..."
./categorize-skills.sh "$NEW_SKILLS_DIR"
3. Move to main collection
3. Move to main collection
echo "Integrating into collection..."
cp -r "$NEW_SKILLS_DIR"/* skills/
echo "Integrating into collection..."
cp -r "$NEW_SKILLS_DIR"/* skills/
4. Update docs
4. Update docs
./generate-docs.sh
echo "✓ Integration complete"
---
**Version**: 1.0.0
**Author**: Harvested from your_claude_skills repository (270+ skills managed)
**Last Updated**: 2025-11-18
**License**: MIT./generate-docs.sh
echo "✓ Integration complete"
---
**版本**: 1.0.0
**作者**: 收集自your_claude_skills仓库(可管理270+技能)
**最后更新**: 2025-11-18
**许可证**: MITQuick Reference
快速参考
bash
undefinedbash
undefinedDownload skills from GitHub repos
Download skills from GitHub repos
./bulk-download-skills.sh repos.txt
./bulk-download-skills.sh repos.txt
Auto-categorize skills
Auto-categorize skills
./categorize-skills.sh skills/
./categorize-skills.sh skills/
Find duplicates
Find duplicates
./find-duplicates.sh skills/
./find-duplicates.sh skills/
Run health check
Run health check
./health-check.sh skills/
./health-check.sh skills/
Generate documentation
Generate documentation
./generate-docs.sh skills/
./generate-docs.sh skills/
Weekly maintenance
Weekly maintenance
./weekly-maintenance.sh
Scale your skill collection management with confidence! 📚./weekly-maintenance.sh
放心地规模化管理你的技能集合吧!📚