#!/usr/bin/env python3 """ Complete Skill Installation Workflow One-command installation: fetch → scrape → enhance → package → upload This CLI tool orchestrates the complete skill installation workflow by calling the install_skill MCP tool. Usage: skill-seekers install --config react skill-seekers install --config configs/custom.json --no-upload skill-seekers install --config django --unlimited skill-seekers install --config react --dry-run Examples: # Install React skill from official configs skill-seekers install --config react # Install from local config file skill-seekers install --config configs/custom.json # Install without uploading skill-seekers install --config django --no-upload # Preview workflow without executing skill-seekers install --config react --dry-run """ import argparse import asyncio import sys from pathlib import Path # Add parent directory to path to import MCP server sys.path.insert(0, str(Path(__file__).parent.parent)) # Import the MCP tool function (with lazy loading) try: from skill_seekers.mcp.server import install_skill_tool MCP_AVAILABLE = True except ImportError: MCP_AVAILABLE = False install_skill_tool = None def main(): """Main entry point for CLI""" # Check MCP availability first if not MCP_AVAILABLE: print("\n❌ Error: MCP package not installed") print("\nThe 'install' command requires MCP support.") print("Install with:") print(" pip install skill-seekers[mcp]") print("\nOr use these alternatives:") print(" skill-seekers scrape --config react") print(" skill-seekers package output/react/") print() sys.exit(1) parser = argparse.ArgumentParser( description="Complete skill installation workflow (fetch → scrape → enhance → package → upload)", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Install React skill from official API skill-seekers install --config react # Install from local config file skill-seekers install --config configs/custom.json # Install without uploading skill-seekers install --config django --no-upload # Unlimited scraping (no page limits) skill-seekers install --config godot --unlimited # Preview workflow (dry run) skill-seekers install --config react --dry-run # Install for Gemini instead of Claude skill-seekers install --config react --target gemini # Install for OpenAI ChatGPT skill-seekers install --config fastapi --target openai Important: - Enhancement is MANDATORY (30-60 sec) for quality (3/10→9/10) - Total time: 20-45 minutes (mostly scraping) - Multi-platform support: claude (default), gemini, openai, markdown - Auto-uploads if API key is set (ANTHROPIC_API_KEY, GOOGLE_API_KEY, or OPENAI_API_KEY) Phases: 1. Fetch config (if config name provided) 2. Scrape documentation 3. AI Enhancement (MANDATORY - no skip option) 4. Package for target platform (ZIP or tar.gz) 5. Upload to target platform (optional) """, ) parser.add_argument( "--config", required=True, help="Config name (e.g., 'react') or path (e.g., 'configs/custom.json')", ) parser.add_argument( "--destination", default="output", help="Output directory for skill files (default: output/)", ) parser.add_argument("--no-upload", action="store_true", help="Skip automatic upload to Claude") parser.add_argument( "--unlimited", action="store_true", help="Remove page limits during scraping (WARNING: Can take hours)", ) parser.add_argument("--dry-run", action="store_true", help="Preview workflow without executing") parser.add_argument( "--target", choices=["claude", "gemini", "openai", "markdown"], default="claude", help="Target LLM platform (default: claude)", ) args = parser.parse_args() # Determine if config is a name or path config_arg = args.config if config_arg.endswith(".json") or "/" in config_arg or "\\" in config_arg: # It's a path config_path = config_arg config_name = None else: # It's a name config_name = config_arg config_path = None # Build arguments for install_skill_tool tool_args = { "config_name": config_name, "config_path": config_path, "destination": args.destination, "auto_upload": not args.no_upload, "unlimited": args.unlimited, "dry_run": args.dry_run, "target": args.target, } # Run async tool try: result = asyncio.run(install_skill_tool(tool_args)) # Print output for content in result: print(content.text) # Return success/failure based on output output_text = result[0].text if "❌" in output_text and "WORKFLOW COMPLETE" not in output_text: return 1 return 0 except KeyboardInterrupt: print("\n\n⚠️ Workflow interrupted by user") return 130 # Standard exit code for SIGINT except Exception as e: print(f"\n\n❌ Unexpected error: {str(e)}") return 1 if __name__ == "__main__": sys.exit(main())