Major restructure to support both CLI usage and MCP integration: **Repository Structure:** - cli/ - All CLI tools (doc_scraper, estimate_pages, enhance_skill, etc.) - mcp/ - New MCP server for Claude Code integration - configs/ - Shared configuration files - tests/ - Updated to import from cli/ - docs/ - Shared documentation **MCP Server (NEW):** - mcp/server.py - Full MCP server implementation - 6 tools available: * generate_config - Create config from URL * estimate_pages - Fast page count estimation * scrape_docs - Full documentation scraping * package_skill - Package to .zip * list_configs - Show available presets * validate_config - Validate config files - mcp/README.md - Complete MCP documentation - mcp/requirements.txt - MCP dependencies **CLI Tools (Moved to cli/):** - All existing functionality preserved - Same commands, same behavior - Tests updated to import from cli.doc_scraper **Tests:** - 68/71 passing (95.8%) - Updated imports from doc_scraper to cli.doc_scraper - Fixed validate_config() tuple unpacking (errors, warnings) - 3 minor test failures (checking warnings instead of errors) **Benefits:** - Use as CLI tool: python3 cli/doc_scraper.py - Use via MCP: Integrated with Claude Code - Shared code and configs - Single source of truth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simple Skill Packager
|
|
Packages a skill directory into a .zip file for Claude.
|
|
|
|
Usage:
|
|
python3 package_skill.py output/steam-inventory/
|
|
python3 package_skill.py output/react/
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
|
|
def package_skill(skill_dir):
|
|
"""Package a skill directory into a .zip file"""
|
|
skill_path = Path(skill_dir)
|
|
|
|
if not skill_path.exists():
|
|
print(f"❌ Error: Directory not found: {skill_dir}")
|
|
return False
|
|
|
|
if not skill_path.is_dir():
|
|
print(f"❌ Error: Not a directory: {skill_dir}")
|
|
return False
|
|
|
|
# Verify SKILL.md exists
|
|
skill_md = skill_path / "SKILL.md"
|
|
if not skill_md.exists():
|
|
print(f"❌ Error: SKILL.md not found in {skill_dir}")
|
|
return False
|
|
|
|
# Create zip filename
|
|
skill_name = skill_path.name
|
|
zip_path = skill_path.parent / f"{skill_name}.zip"
|
|
|
|
print(f"📦 Packaging skill: {skill_name}")
|
|
print(f" Source: {skill_path}")
|
|
print(f" Output: {zip_path}")
|
|
|
|
# Create zip file
|
|
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
|
|
for root, dirs, files in os.walk(skill_path):
|
|
# Skip backup files
|
|
files = [f for f in files if not f.endswith('.backup')]
|
|
|
|
for file in files:
|
|
file_path = Path(root) / file
|
|
arcname = file_path.relative_to(skill_path)
|
|
zf.write(file_path, arcname)
|
|
print(f" + {arcname}")
|
|
|
|
# Get zip size
|
|
zip_size = zip_path.stat().st_size
|
|
print(f"\n✅ Package created: {zip_path}")
|
|
print(f" Size: {zip_size:,} bytes ({zip_size / 1024:.1f} KB)")
|
|
|
|
return True
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python3 package_skill.py <skill_directory>")
|
|
print()
|
|
print("Examples:")
|
|
print(" python3 package_skill.py output/steam-inventory/")
|
|
print(" python3 package_skill.py output/react/")
|
|
sys.exit(1)
|
|
|
|
skill_dir = sys.argv[1]
|
|
success = package_skill(skill_dir)
|
|
sys.exit(0 if success else 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|