From 50c10b6e7597443c4b5154c278bef86b069ca30d Mon Sep 17 00:00:00 2001 From: mika kuns Date: Thu, 4 Jun 2026 19:22:08 +0200 Subject: [PATCH] feat(logging): tag UI task actions with TaskId + debug trace lines --- src/ClaudeDo.App/Program.cs | 4 +- src/ClaudeDo.Ui/ClaudeDo.Ui.csproj | 2 + src/ClaudeDo.Ui/Services/WorkerClient.cs | 60 ++++++++++++------------ 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/ClaudeDo.App/Program.cs b/src/ClaudeDo.App/Program.cs index 5706beb..f3bda26 100644 --- a/src/ClaudeDo.App/Program.cs +++ b/src/ClaudeDo.App/Program.cs @@ -106,7 +106,9 @@ sealed class Program // Services sc.AddSingleton(); - sc.AddSingleton(sp => new WorkerClient(sp.GetRequiredService().SignalRUrl)); + sc.AddSingleton(sp => new WorkerClient( + sp.GetRequiredService().SignalRUrl, + sp.GetRequiredService>())); sc.AddSingleton(sp => sp.GetRequiredService()); // Release check + installer update diff --git a/src/ClaudeDo.Ui/ClaudeDo.Ui.csproj b/src/ClaudeDo.Ui/ClaudeDo.Ui.csproj index 47a97fb..ac343b2 100644 --- a/src/ClaudeDo.Ui/ClaudeDo.Ui.csproj +++ b/src/ClaudeDo.Ui/ClaudeDo.Ui.csproj @@ -11,7 +11,9 @@ + + diff --git a/src/ClaudeDo.Ui/Services/WorkerClient.cs b/src/ClaudeDo.Ui/Services/WorkerClient.cs index 92e5813..471e03e 100644 --- a/src/ClaudeDo.Ui/Services/WorkerClient.cs +++ b/src/ClaudeDo.Ui/Services/WorkerClient.cs @@ -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 _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 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) + /// Invoke a task-targeted hub method under a TaskId log scope, emitting a debug trace line. + 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 MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage) { @@ -264,10 +272,8 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC public Task GetMergeTargetsAsync(string taskId) => TryInvokeAsync("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 CleanupFinishedWorktreesAsync(string? listId = null) => TryInvokeAsync("CleanupFinishedWorktrees", listId);