"""Das Arbeitsverzeichnis eines Projekts — dort implementiert der Agent. Der Pfad liegt als eine Zeile im Projektordner und wandert beim Umbenennen mit. Er ist eine Eigenschaft des Projekts, nicht der Planung: gelesen und geschrieben wird immer im Projektstand, damit ein Planungsabbruch ihn nicht mitnimmt. """ import os from pathlib import Path import projekte DATEI = ".verzeichnis" def _pfad(projekt: str): return projekte.stand(projekt) / DATEI def lies(projekt: str) -> str: """Der eingestellte Pfad, oder leer.""" try: return _pfad(projekt).read_text().strip() except OSError: return "" def pruefe(pfad: str) -> Path: """Taugt der Pfad als Arbeitsverzeichnis? Gibt ihn aufgelöst zurück oder wirft.""" pfad = (pfad or "").strip() if not pfad: raise ValueError("Kein Pfad angegeben") ziel = Path(os.path.expanduser(pfad)) if not ziel.is_absolute(): raise ValueError("Der Pfad muss absolut sein") ziel = ziel.resolve() if not ziel.is_dir(): raise FileNotFoundError(f"„{ziel}“ ist kein Verzeichnis") if ziel == Path(ziel.anchor) or ziel == Path.home(): # Die Wurzel oder das ganze Heimatverzeichnis ist immer ein Fehlgriff raise ValueError("Bitte ein Projektverzeichnis wählen, nicht die Wurzel") return ziel def setze(projekt: str, pfad: str) -> str: ziel = pruefe(pfad) _pfad(projekt).write_text(f"{ziel}\n") return str(ziel) def loesche(projekt: str): _pfad(projekt).unlink(missing_ok=True) def ordner(pfad: str = "") -> dict: """Ein Verzeichnis zum Durchblättern: Unterordner, ohne Verstecktes. Kein Pfad heißt Heimatverzeichnis — dort beginnt die Suche. Die Auswahl trifft der Mensch; hier wird nur gelistet, nie geschrieben. """ ziel = Path(os.path.expanduser(pfad.strip())) if pfad.strip() else Path.home() if not ziel.is_absolute(): raise ValueError("Der Pfad muss absolut sein") ziel = ziel.resolve() if not ziel.is_dir(): raise FileNotFoundError(f"„{ziel}“ ist kein Verzeichnis") try: unter = sorted( (e.name for e in ziel.iterdir() if e.is_dir() and not e.name.startswith(".")), key=str.lower) except PermissionError: raise ValueError(f"„{ziel}“ ist nicht lesbar") eltern = str(ziel.parent) if ziel.parent != ziel else "" return {"pfad": str(ziel), "eltern": eltern, "ordner": unter}