using ClaudeDo.Data.Models; using Microsoft.AspNetCore.SignalR; namespace ClaudeDo.Worker.Hub; public sealed class HubBroadcaster { private readonly IHubContext _hub; public HubBroadcaster(IHubContext hub) => _hub = hub; public Task TaskStarted(string slot, string taskId, DateTime startedAt) => _hub.Clients.All.SendAsync("TaskStarted", slot, taskId, startedAt); public Task TaskFinished(string slot, string taskId, string status, DateTime finishedAt) => _hub.Clients.All.SendAsync("TaskFinished", slot, taskId, status, finishedAt); public Task TaskMessage(string taskId, string ndjsonLine) => _hub.Clients.All.SendAsync("TaskMessage", taskId, ndjsonLine); public Task WorktreeUpdated(string taskId) => _hub.Clients.All.SendAsync("WorktreeUpdated", taskId); public Task TaskUpdated(string taskId) => _hub.Clients.All.SendAsync("TaskUpdated", taskId); public Task ListUpdated(string listId) => _hub.Clients.All.SendAsync("ListUpdated", listId); public Task RunCreated(string taskId, int runNumber, bool isRetry) => _hub.Clients.All.SendAsync("RunCreated", taskId, runNumber, isRetry); public Task WorkerLog(string message, WorkerLogLevel level, DateTime timestampUtc) => _hub.Clients.All.SendAsync("WorkerLog", message, level, timestampUtc); public Task PlanningMergeStarted(string planningTaskId, string targetBranch) => _hub.Clients.All.SendAsync("PlanningMergeStarted", planningTaskId, targetBranch); public Task PlanningSubtaskMerged(string planningTaskId, string subtaskId) => _hub.Clients.All.SendAsync("PlanningSubtaskMerged", planningTaskId, subtaskId); public Task PlanningMergeConflict(string planningTaskId, string subtaskId, IReadOnlyList files) => _hub.Clients.All.SendAsync("PlanningMergeConflict", planningTaskId, subtaskId, files); public Task PlanningMergeAborted(string planningTaskId) => _hub.Clients.All.SendAsync("PlanningMergeAborted", planningTaskId); public Task PlanningCompleted(string planningTaskId) => _hub.Clients.All.SendAsync("PlanningCompleted", planningTaskId); }