"""Milestone abstraction for the UI-agnostic installer core.""" from __future__ import annotations from abc import ABC, abstractmethod from typing import Callable, Iterable, Sequence from .state import InstallerState ProgressCallback = Callable[[str, float | None], None] ValidationResult = str | Sequence[str] | None class Milestone(ABC): """Base class for installer milestones. Milestones encapsulate business logic, validation, and flow control. They must not import or depend on UI toolkits. """ id: str title: str def __init__(self, milestone_id: str, title: str): self.id = milestone_id self.title = title def validate(self, state: InstallerState) -> ValidationResult: """Return a validation error or None when valid.""" return None @abstractmethod def execute(self, state: InstallerState, progress: ProgressCallback | None = None) -> None: """Execute milestone logic. Use the progress callback to emit updates.""" raise NotImplementedError def next(self, state: InstallerState) -> str | None: """Return the next milestone id or None to finish.""" return None