Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:01:20 +08:00
commit 650cfdbc05
15 changed files with 4252 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
#!/bin/bash
# Check if Skill_Seekers is installed and working
SEEKERS_PATH="${SKILL_SEEKERS_PATH:-$HOME/Skill_Seekers}"
if [ ! -d "$SEEKERS_PATH" ]; then
echo "❌ Skill_Seekers not found at $SEEKERS_PATH"
echo ""
echo "Install with: $( cd "$(dirname "$0")" && pwd )/install-skill-seekers.sh"
exit 1
fi
# Check Python
if ! command -v python3 &> /dev/null; then
echo "❌ Python 3 not found"
exit 1
fi
# Check dependencies
cd "$SEEKERS_PATH"
if python3 -c "import cli.doc_scraper" 2>/dev/null; then
echo "✅ Skill_Seekers installed and working"
echo " Location: $SEEKERS_PATH"
exit 0
else
echo "⚠️ Skill_Seekers found but dependencies missing"
echo " Fix: cd $SEEKERS_PATH && pip3 install -r requirements.txt"
exit 1
fi

View File

@@ -0,0 +1,103 @@
#!/bin/bash
# One-command Skill_Seekers installation for skill-factory
set -e
INSTALL_DIR="${SKILL_SEEKERS_PATH:-$HOME/Skill_Seekers}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Skill_Seekers Installation"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Install location: $INSTALL_DIR"
echo ""
# Check if already installed
if [ -d "$INSTALL_DIR" ]; then
echo "⚠️ Skill_Seekers already exists at $INSTALL_DIR"
echo ""
echo "Options:"
echo " 1. Update existing installation"
echo " 2. Reinstall (delete and clone fresh)"
echo " 3. Cancel"
echo ""
read -p "Choice (1-3): " choice
case $choice in
1)
echo "📥 Updating..."
cd "$INSTALL_DIR"
git pull
;;
2)
echo "🗑️ Removing old installation..."
rm -rf "$INSTALL_DIR"
echo "📥 Cloning fresh copy..."
git clone https://github.com/yusufkaraaslan/Skill_Seekers "$INSTALL_DIR"
;;
3)
echo "❌ Cancelled"
exit 0
;;
*)
echo "Invalid choice"
exit 1
;;
esac
else
echo "📥 Cloning Skill_Seekers..."
git clone https://github.com/yusufkaraaslan/Skill_Seekers "$INSTALL_DIR"
fi
# Install Python dependencies
echo ""
echo "📦 Installing Python dependencies..."
cd "$INSTALL_DIR"
if command -v pip3 &> /dev/null; then
pip3 install -r requirements.txt
elif command -v pip &> /dev/null; then
pip install -r requirements.txt
else
echo "❌ pip not found. Please install Python 3.10+ with pip"
exit 1
fi
# Optional: Setup MCP if Claude Code detected
echo ""
if command -v claude &> /dev/null; then
echo "Claude Code detected."
read -p "Install MCP integration? (y/n): " install_mcp
if [[ "$install_mcp" =~ ^[Yy]$ ]]; then
if [ -f "./setup_mcp.sh" ]; then
./setup_mcp.sh
else
echo "⚠️ setup_mcp.sh not found, skipping MCP setup"
fi
fi
fi
# Verify installation
echo ""
echo "✅ Verifying installation..."
if python3 -c "import cli.doc_scraper" 2>/dev/null; then
echo "✅ Skill_Seekers installed successfully!"
else
echo "⚠️ Installation complete but verification failed"
echo " Try manually: cd $INSTALL_DIR && python3 -c 'import cli.doc_scraper'"
exit 1
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Installation Complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Set environment variable (optional):"
echo " export SKILL_SEEKERS_PATH=$INSTALL_DIR"
echo ""
echo "Test installation:"
echo " cd $INSTALL_DIR && python3 cli/doc_scraper.py --help"
echo ""
echo "Ready to use in skill-factory!"

View File

@@ -0,0 +1,220 @@
#!/usr/bin/env python3
"""
Quality checker for Claude skills based on Anthropic best practices.
Returns score 0-10 and lists issues.
"""
import sys
import re
from pathlib import Path
def check_description(frontmatter):
"""Check description quality (2.0 points)"""
desc = frontmatter.get('description', '')
score = 0.0
issues = []
if not desc:
issues.append("Missing description")
return score, issues
# Length check
if len(desc) < 50:
issues.append("Description too short (< 50 chars)")
else:
score += 0.5
# Specificity check
vague_words = ['helps with', 'tool for', 'useful', 'handles']
if any(word in desc.lower() for word in vague_words):
issues.append("Description contains vague phrases")
else:
score += 0.5
# when_to_use check
if 'when ' in desc.lower() or 'use when' in desc.lower():
score += 0.5
else:
issues.append("Description missing 'when to use' guidance")
# Third person check
if not any(word in desc.lower() for word in ['you', 'your', 'i ', "i'm"]):
score += 0.5
else:
issues.append("Description should be third person")
return min(score, 2.0), issues
def check_name(frontmatter):
"""Check name convention (0.5 points)"""
name = frontmatter.get('name', '')
score = 0.0
issues = []
if not name:
issues.append("Missing name")
return score, issues
# Lowercase and hyphens
if name == name.lower() and '-' in name:
score += 0.25
else:
issues.append("Name should be lowercase-with-hyphens")
# Not too generic
if name not in ['helper', 'utils', 'tool', 'skill']:
score += 0.25
else:
issues.append("Name too generic")
return min(score, 0.5), issues
def check_conciseness(content):
"""Check length (1.5 points)"""
lines = content.count('\n')
if lines < 300:
return 1.5, []
elif lines < 500:
return 1.0, []
elif lines < 800:
return 0.5, [f"SKILL.md is {lines} lines (recommend <500)"]
else:
return 0.0, [f"SKILL.md is {lines} lines (way over 500 limit)"]
def check_examples(content):
"""Check for code examples (1.0 points)"""
code_blocks = len(re.findall(r'```[\w]*\n', content))
issues = []
if code_blocks == 0:
issues.append("No code examples found")
return 0.0, issues
elif code_blocks < 3:
issues.append(f"Only {code_blocks} code examples (recommend 5+)")
return 0.5, issues
else:
return 1.0, []
def check_structure(content):
"""Check structure (1.0 points)"""
issues = []
score = 1.0
# Required sections
if '## Overview' not in content and '## What' not in content:
issues.append("Missing overview section")
score -= 0.3
if '## Usage' not in content and '## How' not in content:
issues.append("Missing usage section")
score -= 0.3
# Windows paths check
if '\\' in content and 'C:\\' in content:
issues.append("Contains Windows-style paths (use Unix /)")
score -= 0.4
return max(score, 0.0), issues
def check_antipatterns(content):
"""Check for anti-patterns (1.0 points)"""
issues = []
score = 1.0
# Time-sensitive info
time_patterns = [r'\d{4}-\d{2}-\d{2}', r'last updated', r'as of \d{4}']
for pattern in time_patterns:
if re.search(pattern, content, re.IGNORECASE):
issues.append("Contains time-sensitive information")
score -= 0.5
break
# Inconsistent terminology
if content.count('skill') + content.count('Skill') > 0:
if content.count('plugin') + content.count('Plugin') > 0:
issues.append("Inconsistent terminology (skill vs plugin)")
score -= 0.5
return max(score, 0.0), issues
def parse_frontmatter(content):
"""Extract YAML frontmatter"""
match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL)
if not match:
return {}
fm = {}
for line in match.group(1).split('\n'):
if ':' in line:
key, value = line.split(':', 1)
fm[key.strip()] = value.strip()
return fm
def score_skill(skill_path):
"""Score a skill file against Anthropic best practices"""
if not Path(skill_path).exists():
print(f"Error: {skill_path} not found")
sys.exit(1)
with open(skill_path, 'r') as f:
content = f.read()
frontmatter = parse_frontmatter(content)
total_score = 0.0
all_issues = []
# Run checks
checks = [
('Description', check_description, frontmatter),
('Name', check_name, frontmatter),
('Conciseness', check_conciseness, content),
('Examples', check_examples, content),
('Structure', check_structure, content),
('Anti-patterns', check_antipatterns, content),
]
for name, check_func, arg in checks:
score, issues = check_func(arg)
total_score += score
if issues:
all_issues.extend([f"{name}: {issue}" for issue in issues])
# Add partial scores for other criteria (simplified)
total_score += 1.0 # Progressive disclosure (assume good if references/ exists)
total_score += 0.5 # Degree of freedom (assume appropriate)
total_score += 0.5 # Dependencies (assume documented)
total_score += 0.5 # Error handling (assume good)
total_score += 0.5 # Testing (assume some testing)
return round(total_score, 1), all_issues
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: quality-check.py <path-to-SKILL.md>")
sys.exit(1)
score, issues = score_skill(sys.argv[1])
print(f"{score}/10")
if issues:
print("\nIssues found:")
for issue in issues:
print(f" - {issue}")
# Exit code: 0 if >= 8.0, 1 otherwise
sys.exit(0 if score >= 8.0 else 1)