#!/usr/bin/env python3 """Pull the repo and rebuild isolated platform workspaces under platform_envs/.""" from __future__ import annotations import argparse import shutil import subprocess from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent ENV_ROOT = REPO_ROOT / "platform_envs" ADAPTER_ROOT = REPO_ROOT / "platform_adapters" COMMON_FILES = [ "AGENTS.md", "GEMINI.md", "README.md", "docs/antigravity-clean-workspace.md", "docs/platform-adapters.md", "scripts/dr.py", "scripts/deploy_adapters.py", ] COMMON_DIRS = [ "configs", "scripts/runtime", "scripts/reporting", ] def run_pull() -> None: subprocess.run(["git", "pull", "--ff-only"], cwd=REPO_ROOT, check=True) def reset_dir(path: Path) -> None: if path.exists(): shutil.rmtree(path) path.mkdir(parents=True, exist_ok=True) def copy_file(rel: str, target_root: Path) -> None: src = REPO_ROOT / rel if not src.exists(): raise FileNotFoundError(src) dst = target_root / rel dst.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dst) def copy_dir(src: Path, dst: Path) -> None: if not src.exists(): raise FileNotFoundError(src) if dst.exists(): shutil.rmtree(dst) shutil.copytree(src, dst, ignore=shutil.ignore_patterns("__pycache__", ".pytest_cache")) def copy_common_workspace(target: Path) -> None: for rel in COMMON_FILES: copy_file(rel, target) for rel in COMMON_DIRS: copy_dir(REPO_ROOT / rel, target / rel) (target / "projects").mkdir(parents=True, exist_ok=True) (target / "projects" / ".gitkeep").touch(exist_ok=True) def build_antigravity() -> Path: target = ENV_ROOT / "antigravity" reset_dir(target) copy_common_workspace(target) copy_dir(ADAPTER_ROOT / "antigravity" / "agent", target / ".agent") return target def build_codex() -> Path: target = ENV_ROOT / "codex" reset_dir(target) copy_common_workspace(target) copy_dir(ADAPTER_ROOT / "codex", target / "codex_home") copy_dir(ADAPTER_ROOT / "antigravity" / "agent" / "skills", target / "codex_home" / "skills") return target def build_opencode() -> Path: target = ENV_ROOT / "opencode" reset_dir(target) copy_common_workspace(target) copy_dir(ADAPTER_ROOT / "opencode", target / ".opencode") return target def build_claude_code() -> Path: target = ENV_ROOT / "claude-code" reset_dir(target) copy_common_workspace(target) copy_dir(ADAPTER_ROOT / "claude-code", target / ".claude") return target def build_gemini_cli() -> Path: target = ENV_ROOT / "gemini-cli" reset_dir(target) copy_common_workspace(target) copy_dir(ADAPTER_ROOT / "gemini-cli", target / ".gemini") return target BUILDERS = { "antigravity": build_antigravity, "codex": build_codex, "opencode": build_opencode, "claude-code": build_claude_code, "gemini-cli": build_gemini_cli, } def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Update isolated Deep Research platform environments") parser.add_argument( "--platform", choices=["all", *BUILDERS.keys()], default="all", help="which platform env to rebuild", ) parser.add_argument("--skip-pull", action="store_true", help="do not run git pull --ff-only first") return parser def main() -> int: args = build_parser().parse_args() if not args.skip_pull: run_pull() names = list(BUILDERS) if args.platform == "all" else [args.platform] ENV_ROOT.mkdir(parents=True, exist_ok=True) for name in names: target = BUILDERS[name]() print(f"rebuilt {name}: {target}") return 0 if __name__ == "__main__": raise SystemExit(main())