|
|
|
|
@@ -6,6 +6,8 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
|
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Serilog.Context;
|
|
|
|
|
|
|
|
|
|
namespace ClaudeDo.Ui.Services;
|
|
|
|
|
|
|
|
|
|
@@ -30,6 +32,7 @@ sealed class IndefiniteRetryPolicy : IRetryPolicy
|
|
|
|
|
public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerClient
|
|
|
|
|
{
|
|
|
|
|
private readonly HubConnection _hub;
|
|
|
|
|
private readonly ILogger<WorkerClient> _logger;
|
|
|
|
|
private CancellationTokenSource? _startCts;
|
|
|
|
|
private Task _retryLoopTask = Task.CompletedTask;
|
|
|
|
|
private readonly object _startLock = new();
|
|
|
|
|
@@ -65,8 +68,9 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|
|
|
|
|
|
|
|
|
public string? LastMergeAllTarget { get; private set; }
|
|
|
|
|
|
|
|
|
|
public WorkerClient(string signalRUrl)
|
|
|
|
|
public WorkerClient(string signalRUrl, ILogger<WorkerClient> logger)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_hub = new HubConnectionBuilder()
|
|
|
|
|
.WithUrl(signalRUrl)
|
|
|
|
|
.WithAutomaticReconnect(new IndefiniteRetryPolicy())
|
|
|
|
|
@@ -240,20 +244,24 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|
|
|
|
catch { return default; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task RunNowAsync(string taskId)
|
|
|
|
|
/// <summary>Invoke a task-targeted hub method under a TaskId log scope, emitting a debug trace line.</summary>
|
|
|
|
|
private async Task InvokeForTaskAsync(string taskId, string method, params object?[] args)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("RunNow", taskId);
|
|
|
|
|
using (LogContext.PushProperty("TaskId", taskId))
|
|
|
|
|
{
|
|
|
|
|
_logger.LogDebug("UI invoking {Method} for task {TaskId}", method, taskId);
|
|
|
|
|
await _hub.InvokeCoreAsync(method, args);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ContinueTaskAsync(string taskId, string followUpPrompt)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("ContinueTask", taskId, followUpPrompt);
|
|
|
|
|
}
|
|
|
|
|
public Task RunNowAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "RunNow", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task ResetTaskAsync(string taskId)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("ResetTask", taskId);
|
|
|
|
|
}
|
|
|
|
|
public Task ContinueTaskAsync(string taskId, string followUpPrompt)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "ContinueTask", taskId, followUpPrompt);
|
|
|
|
|
|
|
|
|
|
public Task ResetTaskAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "ResetTask", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task<MergeResultDto> MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage)
|
|
|
|
|
{
|
|
|
|
|
@@ -264,10 +272,8 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|
|
|
|
public Task<MergeTargetsDto?> GetMergeTargetsAsync(string taskId)
|
|
|
|
|
=> TryInvokeAsync<MergeTargetsDto>("GetMergeTargets", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task CancelTaskAsync(string taskId)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("CancelTask", taskId);
|
|
|
|
|
}
|
|
|
|
|
public Task CancelTaskAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "CancelTask", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task WakeQueueAsync()
|
|
|
|
|
{
|
|
|
|
|
@@ -386,25 +392,17 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|
|
|
|
await _hub.InvokeAsync("SetTaskStatus", taskId, status.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ApproveReviewAsync(string taskId)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("ApproveReview", taskId);
|
|
|
|
|
}
|
|
|
|
|
public Task ApproveReviewAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "ApproveReview", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task RejectReviewToQueueAsync(string taskId, string feedback)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("RejectReviewToQueue", taskId, feedback);
|
|
|
|
|
}
|
|
|
|
|
public Task RejectReviewToQueueAsync(string taskId, string feedback)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "RejectReviewToQueue", taskId, feedback);
|
|
|
|
|
|
|
|
|
|
public async Task RejectReviewToIdleAsync(string taskId)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("RejectReviewToIdle", taskId);
|
|
|
|
|
}
|
|
|
|
|
public Task RejectReviewToIdleAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "RejectReviewToIdle", taskId);
|
|
|
|
|
|
|
|
|
|
public async Task CancelReviewAsync(string taskId)
|
|
|
|
|
{
|
|
|
|
|
await _hub.InvokeAsync("CancelReview", taskId);
|
|
|
|
|
}
|
|
|
|
|
public Task CancelReviewAsync(string taskId)
|
|
|
|
|
=> InvokeForTaskAsync(taskId, "CancelReview", taskId);
|
|
|
|
|
|
|
|
|
|
public Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null)
|
|
|
|
|
=> TryInvokeAsync<WorktreeCleanupDto>("CleanupFinishedWorktrees", listId);
|
|
|
|
|
|