namespace ClaudeDo.Worker.Queue; /// /// Owns the wake semaphore. Producers (state mutations, hub) call Wake(); /// the queue dispatcher awaits WaitAsync. /// public sealed class QueueWaker : IQueueWaker { private readonly SemaphoreSlim _signal = new(0, 1); public void Wake() { try { _signal.Release(); } catch (SemaphoreFullException) { /* already signalled */ } } public Task WaitAsync(CancellationToken ct) => _signal.WaitAsync(ct); }