fix: Add YAML frontmatter to unified, GitHub, and PDF skill builders
**Problem:** (PR #170 verified) Three skill builders were generating SKILL.md files without YAML frontmatter, making skills invisible to Claude after upload: - unified_skill_builder.py - github_scraper.py - pdf_scraper.py Only doc_scraper.py had frontmatter implemented. **Root Cause:** Claude requires YAML frontmatter with 'name' and 'description' fields to recognize and index skills. Without it, uploaded skills don't appear in skill lists and can't be triggered. **Fix:** Added consistent frontmatter generation to all three builders: - Normalizes skill name (lowercase, hyphens, max 64 chars) - Truncates description to 1024 chars (Claude requirement) - Generates YAML frontmatter with proper formatting **Test Results:** ✅ All 390/390 tests passing (0 failures, 0 skipped) ✅ Consistent implementation across all builders ✅ Meets Claude's official skill specification **Example Output:** ```yaml --- name: my-skill-name description: Skill description here --- # My Skill Name ... ``` **Credits:** Original fix by @AbdelrahmanHafez in PR #170 Rebased to current development by Claude Code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: AbdelrahmanHafez <AbdelrahmanHafez@users.noreply.github.com>
This commit is contained in:
@@ -536,7 +536,18 @@ class GitHubToSkillConverter:
|
||||
"""Generate main SKILL.md file."""
|
||||
repo_info = self.data.get('repo_info', {})
|
||||
|
||||
skill_content = f"""# {repo_info.get('name', self.name)}
|
||||
# Generate skill name (lowercase, hyphens only, max 64 chars)
|
||||
skill_name = self.name.lower().replace('_', '-').replace(' ', '-')[:64]
|
||||
|
||||
# Truncate description to 1024 chars if needed
|
||||
desc = self.description[:1024] if len(self.description) > 1024 else self.description
|
||||
|
||||
skill_content = f"""---
|
||||
name: {skill_name}
|
||||
description: {desc}
|
||||
---
|
||||
|
||||
# {repo_info.get('name', self.name)}
|
||||
|
||||
{self.description}
|
||||
|
||||
|
||||
@@ -272,7 +272,19 @@ class PDFToSkillConverter:
|
||||
"""Generate main SKILL.md file"""
|
||||
filename = f"{self.skill_dir}/SKILL.md"
|
||||
|
||||
# Generate skill name (lowercase, hyphens only, max 64 chars)
|
||||
skill_name = self.name.lower().replace('_', '-').replace(' ', '-')[:64]
|
||||
|
||||
# Truncate description to 1024 chars if needed
|
||||
desc = self.description[:1024] if len(self.description) > 1024 else self.description
|
||||
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
# Write YAML frontmatter
|
||||
f.write(f"---\n")
|
||||
f.write(f"name: {skill_name}\n")
|
||||
f.write(f"description: {desc}\n")
|
||||
f.write(f"---\n\n")
|
||||
|
||||
f.write(f"# {self.name.title()} Documentation Skill\n\n")
|
||||
f.write(f"{self.description}\n\n")
|
||||
|
||||
|
||||
@@ -73,7 +73,18 @@ class UnifiedSkillBuilder:
|
||||
"""Generate main SKILL.md file."""
|
||||
skill_path = os.path.join(self.skill_dir, 'SKILL.md')
|
||||
|
||||
content = f"""# {self.name.title()}
|
||||
# Generate skill name (lowercase, hyphens only, max 64 chars)
|
||||
skill_name = self.name.lower().replace('_', '-').replace(' ', '-')[:64]
|
||||
|
||||
# Truncate description to 1024 chars if needed
|
||||
desc = self.description[:1024] if len(self.description) > 1024 else self.description
|
||||
|
||||
content = f"""---
|
||||
name: {skill_name}
|
||||
description: {desc}
|
||||
---
|
||||
|
||||
# {self.name.title()}
|
||||
|
||||
{self.description}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user