"""brain sync — Create a versioned snapshot of the active Brain Instance.""" import shutil import typer from brain.config import get_active_brain from brain.paths import get_workspace_dir from brain.utils.display import error, success, info import json def sync() -> None: """Snapshot the active Brain Instance into versions/vN/.""" active = get_active_brain() if not active or not active.exists(): error("No active Brain selected.") error("Run: brain use ") raise typer.Exit(code=1) versions_dir = active / "versions" versions_dir.mkdir(exist_ok=True) # Determine next version number existing = [ d for d in versions_dir.iterdir() if d.is_dir() and d.name.startswith("v") and d.name[1:].isdigit() ] if existing: latest_num = max(int(d.name[1:]) for d in existing) next_num = latest_num + 1 else: next_num = 1 version_name = f"v{next_num}" target = versions_dir / version_name # Full copy, EXCLUDING versions/ to avoid recursive growth def _ignore_versions(directory: str, contents: list[str]) -> list[str]: if directory == str(active): return ["versions"] return [] shutil.copytree(str(active), str(target), ignore=_ignore_versions) # Update workspace BRAIN.json if connected workspace = get_workspace_dir() if workspace.exists(): brain_json_path = workspace / "BRAIN.json" if brain_json_path.exists(): brain_json = json.loads(brain_json_path.read_text(encoding="utf-8")) brain_json["version"] = version_name brain_json_path.write_text( json.dumps(brain_json, indent=2), encoding="utf-8" ) success(f"Brain synced -> {version_name}") info(f"Snapshot: {target}")