feat(ui): worker client surface for in-app interactive sessions

Adds SendInteractiveMessageAsync/StopInteractiveSessionAsync and the
InteractiveSessionStarted/Ended events to IWorkerClient + WorkerClient
(UI-thread dispatch mirroring TaskQuestionAsked). Updates the IWorkerClient
fakes in both test projects.
This commit is contained in:
Mika Kuns
2026-06-26 09:22:53 +02:00
parent 30e87e698e
commit 9effddeb2c
4 changed files with 37 additions and 0 deletions

View File

@@ -49,6 +49,8 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
public event Action<string>? TaskUpdatedEvent;
public event Action<string, string, string>? TaskQuestionAskedEvent;
public event Action<string, string>? TaskQuestionResolvedEvent;
public event Action<string>? InteractiveSessionStartedEvent;
public event Action<string>? InteractiveSessionEndedEvent;
public event Action? ConnectionRestoredEvent;
public event Action<string>? WorktreeUpdatedEvent;
public event Action<string>? ListUpdatedEvent;
@@ -148,6 +150,16 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
Dispatcher.UIThread.Post(() => TaskQuestionResolvedEvent?.Invoke(taskId, questionId));
});
_hub.On<string>("InteractiveSessionStarted", taskId =>
{
Dispatcher.UIThread.Post(() => InteractiveSessionStartedEvent?.Invoke(taskId));
});
_hub.On<string>("InteractiveSessionEnded", taskId =>
{
Dispatcher.UIThread.Post(() => InteractiveSessionEndedEvent?.Invoke(taskId));
});
_hub.On<string>("WorktreeUpdated", taskId =>
{
Dispatcher.UIThread.Post(() => WorktreeUpdatedEvent?.Invoke(taskId));
@@ -279,6 +291,18 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
catch { /* offline or already resolved — the UI clears optimistically */ }
}
public async Task SendInteractiveMessageAsync(string taskId, string text)
{
try { await _hub.InvokeAsync("SendInteractiveMessage", taskId, text); }
catch { /* offline or session already ended */ }
}
public async Task StopInteractiveSessionAsync(string taskId)
{
try { await _hub.InvokeAsync("StopInteractiveSession", taskId); }
catch { /* offline */ }
}
public Task<PendingQuestionDto?> GetPendingQuestionAsync(string taskId)
=> TryInvokeAsync<PendingQuestionDto>("GetPendingQuestion", taskId);