from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime from typing import Callable, TYPE_CHECKING if TYPE_CHECKING: from .executor import ExecutionContext TaskHandler = Callable[["ExecutionContext"], "TaskResult"] @dataclass(frozen=True) class TaskDefinition: key: str label: str description: str category: str handler: TaskHandler requires_root: bool = True default_selected: bool = False @dataclass class TaskResult: key: str label: str success: bool changed: bool started_at: datetime finished_at: datetime details: list[str] = field(default_factory=list) error: str | None = None @property def duration_seconds(self) -> float: return (self.finished_at - self.started_at).total_seconds() @dataclass class Scenario: name: str task_keys: list[str] description: str = "" builtin: bool = False