class MiniError(RuntimeError):
    """A user-actionable, non-destructive stop."""


class Cancelled(MiniError):
    pass


class GameClientClosed(MiniError):
    """The owned game window closed; stop instead of retrying its UI."""


class InputInterrupted(MiniError):
    """Focus changed before a physical input; a fresh observation may retry."""


class ObservationUnavailable(MiniError):
    """A temporary read/capture failure; retry this observation, not the task."""


class DungeonObservationPending(MiniError):
    """A dungeon observation needs recovery, not termination of the run."""

class CoordinatePreparationRequired(MiniError):
    """Manual screen confirmation is required; never retry by recalculating."""


def require(condition, message):
    if not condition:
        raise MiniError(message)
