Files
skill-seekers-reference/cli/package_skill.py
yusyus ae924a9d05 Refactor: Convert to monorepo with CLI and MCP server
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>
2025-10-19 15:19:53 +03:00

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()