"""Resolve myclaude repository root for make / editable install flows.""" import os from pathlib import Path def _pyproject_names_myclaude(path: Path) -> bool: try: text = path.read_text(encoding="utf-8", errors="ignore") except OSError: return False return 'name = "myclaude"' in text or "name = 'myclaude'" in text def _walk_up_for_pyproject(start: Path) -> Path | None: p = start.resolve() for _ in range(16): candidate = p / "pyproject.toml" if candidate.is_file() and _pyproject_names_myclaude(candidate): return p parent = p.parent if parent == p: break p = parent return None def get_myclaude_project_root() -> Path: """ Root of the myclaude repo (contains Makefile + pyproject). Order: MYCLAUDE_PROJECT_ROOT > walk from cwd > package source tree > ~/.myclaude """ env_root = os.environ.get("MYCLAUDE_PROJECT_ROOT") if env_root: return Path(env_root).resolve() try: cwd = Path.cwd() except (OSError, PermissionError): cwd = None if cwd is not None: found = _walk_up_for_pyproject(cwd) if found is not None: return found here = Path(__file__).resolve().parent for _ in range(8): pyproject = here / "pyproject.toml" if pyproject.is_file() and _pyproject_names_myclaude(pyproject): return here if here.parent == here: break here = here.parent return Path.home() / ".myclaude"