#!/usr/bin/env python """ .NET Forge Ultra - CLI Management Tool Complete command-line interface for managing your reverse engineering workstation """ import argparse import os import sys import subprocess import json from pathlib import Path from datetime import datetime # Colors for terminal class Colors: HEADER = '\033[95m' OKBLUE = '\033[94m' OKCYAN = '\033[96m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' UNDERLINE = '\033[4m' def print_header(text): print(f"\n{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}") print(f"{Colors.HEADER}{Colors.BOLD} {text}{Colors.ENDC}") print(f"{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}\n") def print_success(text): print(f"[OK] {text}") def print_error(text): print(f"[ERROR] {text}") def print_warning(text): print(f"[WARN] {text}") def print_info(text): print(f"[INFO] {text}") def run_command(cmd, cwd=None, check=True): """Run shell command and return result""" try: result = subprocess.run( cmd, shell=True, cwd=cwd, capture_output=True, text=True, check=check ) return result.returncode == 0, result.stdout, result.stderr except subprocess.CalledProcessError as e: return False, e.stdout or "", e.stderr or "" def check_hf_login(): """Check if logged in to HuggingFace""" try: from huggingface_hub import HfApi api = HfApi() user = api.whoami() return True, user["name"] except: return False, None def hf_login(): """Login to HuggingFace via CLI""" print_header("HuggingFace Login") print_info("Starting authentication...") print_info("If browser doesn't open, go to: https://huggingface.co/settings/tokens") print_info("Create a token and paste it below:\n") try: from huggingface_hub import login, interpreter_login interpreter_login() print_success("Logged in to HuggingFace") return True except Exception as e: print_error(f"Login failed: {e}") return False def create_space(name, sdk="gradio", hardware="cpu-basic"): """Create HuggingFace Space""" print_info(f"Creating space: {name} (SDK: {sdk}, Hardware: {hardware})") try: from huggingface_hub import create_repo create_repo( repo_id=name, repo_type="space", space_sdk=sdk, space_hardware=hardware, exist_ok=True ) print_success(f"Space created: {name}") return True except Exception as e: print_error(f"Failed to create space: {e}") return False def deploy_to_space(space_name, files, sdk="gradio"): """Deploy files to HuggingFace Space""" print_info(f"Deploying to {space_name}...") try: from huggingface_hub import upload_file for file in files: if os.path.exists(file): print_info(f"Uploading {file}...") upload_file( path_or_fileobj=file, path_in_repo=os.path.basename(file), repo_id=space_name, repo_type="space", ) print_success(f"Uploaded {file}") else: print_warning(f"File not found: {file}") return True except Exception as e: print_error(f"Deployment failed: {e}") return False def set_space_secret(space_name, key, value): """Set space secret via API""" print_info(f"Setting secret {key} for {space_name}") # Note: Secrets must be set via web UI or API with proper auth print_warning("Secrets must be set via HuggingFace web UI:") print_info(f" https://huggingface.co/spaces/{space_name}/settings") return True def check_space_status(space_name): """Check space deployment status""" print_info(f"Checking status of {space_name}...") try: from huggingface_hub import HfApi api = HfApi() space = api.space_info(space_name) print_success(f"Space exists: {space.id}") print_info(f"SDK: {space.sdk}") print_info(f"Last modified: {space.lastModified}") return True except Exception as e: print_error(f"Space not found: {e}") return False def list_spaces(): """List all user spaces""" print_header("Your HuggingFace Spaces") try: from huggingface_hub import HfApi api = HfApi() user = api.whoami() spaces = api.list_spaces(author=user["name"]) for space in spaces: print(f"\n {Colors.OKCYAN}{space.id}{Colors.ENDC}") print(f" SDK: {space.sdk}") print(f" URL: https://huggingface.co/spaces/{space.id}") return True except Exception as e: print_error(f"Failed to list spaces: {e}") return False def install_requirements(req_file): """Install Python requirements""" print_info(f"Installing requirements from {req_file}...") success, stdout, stderr = run_command(f"pip install -r {req_file}") if success: print_success("Requirements installed") return True else: print_error(f"Failed: {stderr}") return False def build_react_app(cwd): """Build React app""" print_info("Building React app...") success, stdout, stderr = run_command("npm run build", cwd=cwd) if success: print_success("Build complete") return True else: print_error(f"Build failed: {stderr}") return False def show_space_url(space_name): """Display space URL""" url = f"https://huggingface.co/spaces/{space_name}" print_header("Space URL") print(f"\n {Colors.OKGREEN}{Colors.BOLD}{url}{Colors.ENDC}\n") def revoke_token_warning(): """Show token revocation warning""" print_header("SECURITY WARNING") print(f"{Colors.FAIL}{Colors.BOLD}If you exposed a HuggingFace token:{Colors.ENDC}\n") print("1. Revoke it immediately:") print(f" {Colors.OKBLUE}https://huggingface.co/settings/tokens{Colors.ENDC}\n") print("2. Create a new token with Read permissions only") print("3. Add it to your Space secrets\n") def main(): parser = argparse.ArgumentParser( description=".NET Forge Ultra - CLI Management Tool", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: %(prog)s login # Login to HuggingFace %(prog)s list # List your spaces %(prog)s deploy dotnet-forge-ultra %(prog)s status dotnet-forge-ultra %(prog)s install # Install requirements %(prog)s build # Build React app %(prog)s url dotnet-forge-ultra """ ) subparsers = parser.add_subparsers(dest="command", help="Commands") # Login command subparsers.add_parser("login", help="Login to HuggingFace") # List command subparsers.add_parser("list", help="List all spaces") # Deploy command deploy_parser = subparsers.add_parser("deploy", help="Deploy to space") deploy_parser.add_argument("space", help="Space name") deploy_parser.add_argument("--files", nargs="+", help="Files to upload") deploy_parser.add_argument("--sdk", default="gradio", help="Space SDK") # Status command status_parser = subparsers.add_parser("status", help="Check space status") status_parser.add_argument("space", help="Space name") # URL command url_parser = subparsers.add_parser("url", help="Show space URL") url_parser.add_argument("space", help="Space name") # Install command install_parser = subparsers.add_parser("install", help="Install requirements") install_parser.add_argument("--file", default="requirements.txt", help="Requirements file") # Build command build_parser = subparsers.add_parser("build", help="Build React app") build_parser.add_argument("--dir", help="App directory") # Security command subparsers.add_parser("security", help="Show security warnings") # Init command init_parser = subparsers.add_parser("init", help="Initialize new space") init_parser.add_argument("name", help="Space name") init_parser.add_argument("--sdk", default="gradio", help="Space SDK") init_parser.add_argument("--hardware", default="cpu-basic", help="Hardware tier") args = parser.parse_args() if args.command == "login": hf_login() elif args.command == "list": list_spaces() elif args.command == "deploy": if not check_hf_login()[0]: print_error("Not logged in. Run: forge login") sys.exit(1) files = args.files or ["app.py", "requirements.txt", "README.md"] deploy_to_space(args.space, files, args.sdk) elif args.command == "status": check_space_status(args.space) elif args.command == "url": show_space_url(args.space) elif args.command == "install": install_requirements(args.file) elif args.command == "build": build_react_app(args.dir or os.getcwd()) elif args.command == "security": revoke_token_warning() elif args.command == "init": if not check_hf_login()[0]: print_error("Not logged in. Run: forge login") sys.exit(1) create_space(args.name, args.sdk, args.hardware) else: parser.print_help() if __name__ == "__main__": main()