, stale: bool}|null */ public function lastRun(): ?array { try { $path = storage_path('app/'.self::FILE); if (! File::exists($path)) { return null; } $data = json_decode((string) File::get($path), true); if (! is_array($data) || ! isset($data['at'])) { return null; } $at = Carbon::parse((string) $data['at']); return [ 'at' => $at, 'outcome' => (string) ($data['outcome'] ?? 'idle'), 'actions' => array_values(array_filter( is_array($data['actions'] ?? null) ? $data['actions'] : [], 'is_string' )), 'stale' => $at->lt(Carbon::now()->subMinutes(self::STALE_AFTER_MINUTES)), ]; } catch (Throwable) { // Dieselbe Haltung wie `UpdateChannel::readJson()`: die Konsole // liest das bei jedem Seitenaufbau, und „ich weiß es nicht" ist // ein brauchbarer Zustand — eine geworfene Ausnahme nicht. return null; } } }