#!/usr/bin/env python3 """ [OPS] Sovereign Skill Installer Part of the Gemini Sovereign Infrastructure Suite. Packages and installs Hermes skills onto remote wizard nodes. """ import os import sys import argparse import subprocess from pathlib import Path # --- CONFIGURATION --- # Assumes hermes-agent is a sibling directory to timmy-config HERMES_ROOT = "../hermes-agent" SKILLS_DIR = "skills" class SkillInstaller: def __init__(self, host: str, ip: str): self.host = host self.ip = ip self.hermes_path = Path(HERMES_ROOT).resolve() def log(self, message: str): print(f"[*] {message}") def error(self, message: str): print(f"[!] ERROR: {message}") sys.exit(1) def install_skill(self, skill_name: str): self.log(f"Installing skill '{skill_name}' to {self.host} ({self.ip})...") skill_path = self.hermes_path / SKILLS_DIR / skill_name if not skill_path.exists(): self.error(f"Skill '{skill_name}' not found in {skill_path}") # 1. Compress skill self.log("Compressing skill...") tar_file = f"{skill_name}.tar.gz" subprocess.run(["tar", "-czf", tar_file, "-C", str(skill_path.parent), skill_name]) # 2. Upload to remote self.log("Uploading to remote...") remote_path = f"/opt/hermes/skills/{skill_name}" subprocess.run(["ssh", f"root@{self.ip}", f"mkdir -p /opt/hermes/skills"]) subprocess.run(["scp", tar_file, f"root@{self.ip}:/tmp/"]) # 3. Extract and register self.log("Extracting and registering...") extract_cmd = f"tar -xzf /tmp/{tar_file} -C /opt/hermes/skills/ && rm /tmp/{tar_file}" subprocess.run(["ssh", f"root@{self.ip}", extract_cmd]) # Registration logic (simplified) # In a real scenario, we'd update the wizard's config.yaml self.log(f"[SUCCESS] Skill '{skill_name}' installed on {self.host}") # Cleanup local tar os.remove(tar_file) def main(): parser = argparse.ArgumentParser(description="Gemini Skill Installer") parser.add_argument("host", help="Target host name") parser.add_argument("ip", help="Target host IP") parser.add_argument("skill", help="Skill name to install") args = parser.parse_args() installer = SkillInstaller(args.host, args.ip) installer.install_skill(args.skill) if __name__ == "__main__": main()