"""Runtime path helpers. All mutable runtime data is resolved from the executable directory when the program is frozen, and from the project root while running from source. """ from __future__ import annotations import os import sys from pathlib import Path def app_root() -> Path: if getattr(sys, "frozen", False): return Path(sys.executable).resolve().parent return Path(__file__).resolve().parents[2] APP_ROOT = app_root() CONFIG_DIR = APP_ROOT / "config" DATA_DIR = APP_ROOT / "data" WEB_DIR = APP_ROOT / "web" LOG_DIR = APP_ROOT / "logs" INTEGRATIONS_DIR = APP_ROOT / "integrations" VENDOR_DIR = APP_ROOT / "vendor" DOTS_TTS_SRC = VENDOR_DIR / "dots.tts-main" / "src" def project_path(value: str | os.PathLike, *, base: Path | None = None) -> Path: path = Path(value) if path.is_absolute(): return path return (base or APP_ROOT) / path def ensure_runtime_dirs() -> None: for path in (CONFIG_DIR, DATA_DIR, WEB_DIR, LOG_DIR): path.mkdir(parents=True, exist_ok=True)