#!/usr/bin/env python3 import os import sys import subprocess # Determine base path: use BMAD_PATH env var, or default to ../../bmad relative to this script # transparent_factory_site/skills/bmad-suite/manager.py -> transparent_factory_site/bmad SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_BMAD_PATH = os.path.abspath(os.path.join(SCRIPT_DIR, "../../bmad")) BASE_PATH = os.environ.get("BMAD_PATH", DEFAULT_BMAD_PATH) REPOS = { "framework": { "url": "https://github.com/bmad-code-org/BMAD-METHOD.git", "path": os.path.join(BASE_PATH, "framework") }, "creative-suite": { "url": "https://github.com/bmad-code-org/bmad-module-creative-intelligence-suite.git", "path": os.path.join(BASE_PATH, "creative-intelligence-suite") }, "tea-module": { "url": "https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise.git", "path": os.path.join(BASE_PATH, "test-architecture-enterprise") } } def update_or_clone(name, config): """Clone if missing, pull if present.""" repo_path = config["path"] repo_url = config["url"] # Ensure parent directory exists so we can clone into it if needed parent_dir = os.path.dirname(repo_path) if not os.path.exists(parent_dir): os.makedirs(parent_dir, exist_ok=True) # Check if it's already a git repo if os.path.exists(os.path.join(repo_path, ".git")): print(f"🔄 Updating {name}...") try: subprocess.run(["git", "pull"], cwd=repo_path, check=True) print(f"✅ {name} updated.") except subprocess.CalledProcessError as e: print(f"❌ {name} update failed: {e}") # Check if directory exists but is empty (safe to clone into) elif os.path.exists(repo_path) and not os.listdir(repo_path): print(f"📥 Cloning {name} into empty directory...") try: subprocess.run(["git", "clone", repo_url, "."], cwd=repo_path, check=True) print(f"✅ {name} cloned.") except subprocess.CalledProcessError as e: print(f"❌ {name} clone failed: {e}") # Directory doesn't exist at all elif not os.path.exists(repo_path): print(f"📥 Cloning {name}...") try: subprocess.run(["git", "clone", repo_url, repo_path], check=True) print(f"✅ {name} cloned.") except subprocess.CalledProcessError as e: print(f"❌ {name} clone failed: {e}") else: print(f"⚠️ Target directory {repo_path} exists and is not empty (and not a git repo). Skipping.") def list_workflows(suite_path): """List available workflows/agents in the suite.""" src_path = os.path.join(suite_path, "src") if not os.path.exists(src_path): # Fallback to listing root if src doesn't exist (e.g. some repos might differ) if os.path.exists(suite_path): return subprocess.getoutput(f"find {suite_path} -maxdepth 3 -name '*.md' -o -name '*.ts' -o -name '*.js' | grep -v 'node_modules' | sort") return "Directory not found." return subprocess.getoutput(f"find {src_path} -name '*.md' -o -name '*.ts' -o -name '*.js' -o -name '*.yaml' | sort") if __name__ == "__main__": action = sys.argv[1] if len(sys.argv) > 1 else "list" if action == "update": print("--- Checking BMad Suite Repositories ---") for name, config in REPOS.items(): update_or_clone(name, config) print("") elif action == "list": for name, config in REPOS.items(): print(f"--- {name} Workflows ---") print(list_workflows(config["path"])) print("") else: print(f"Unknown action: {action}")