From c53b5878cf53f3f7c57dfd1fe12149034974de96 Mon Sep 17 00:00:00 2001 From: Mika Kuns Date: Wed, 22 Apr 2026 09:44:22 +0200 Subject: [PATCH] feat(worker): expose MergeTask and GetMergeTargets on WorkerHub --- src/ClaudeDo.Worker/Hub/WorkerHub.cs | 47 +++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/ClaudeDo.Worker/Hub/WorkerHub.cs b/src/ClaudeDo.Worker/Hub/WorkerHub.cs index 895c965..96f25e1 100644 --- a/src/ClaudeDo.Worker/Hub/WorkerHub.cs +++ b/src/ClaudeDo.Worker/Hub/WorkerHub.cs @@ -22,6 +22,8 @@ public record AppSettingsDto( public record WorktreeCleanupDto(int Removed); public record WorktreeResetDto(int Removed, int TasksAffected, bool Blocked, int RunningTasks); +public record MergeResultDto(string Status, IReadOnlyList ConflictFiles, string? ErrorMessage); +public record MergeTargetsDto(string DefaultBranch, IReadOnlyList LocalBranches); public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub { @@ -34,6 +36,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub private readonly IDbContextFactory _dbFactory; private readonly WorktreeMaintenanceService _wtMaintenance; private readonly TaskResetService _resetService; + private readonly TaskMergeService _mergeService; public WorkerHub( QueueService queue, @@ -41,7 +44,8 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub HubBroadcaster broadcaster, IDbContextFactory dbFactory, WorktreeMaintenanceService wtMaintenance, - TaskResetService resetService) + TaskResetService resetService, + TaskMergeService mergeService) { _queue = queue; _agentService = agentService; @@ -49,6 +53,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub _dbFactory = dbFactory; _wtMaintenance = wtMaintenance; _resetService = resetService; + _mergeService = mergeService; } public string Ping() => $"pong v{Version}"; @@ -160,4 +165,44 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub var result = await _wtMaintenance.ResetAllAsync(); return new WorktreeResetDto(result.Removed, result.TasksAffected, result.Blocked, result.RunningTasks); } + + public async Task MergeTask( + string taskId, string targetBranch, bool removeWorktree, string commitMessage) + { + try + { + var r = await _mergeService.MergeAsync( + taskId, + targetBranch ?? "", + removeWorktree, + string.IsNullOrWhiteSpace(commitMessage) ? "Merge task" : commitMessage, + CancellationToken.None); + return new MergeResultDto(r.Status, r.ConflictFiles, r.ErrorMessage); + } + catch (KeyNotFoundException) + { + throw new HubException("task not found"); + } + catch (InvalidOperationException ex) + { + throw new HubException(ex.Message); + } + } + + public async Task GetMergeTargets(string taskId) + { + try + { + var t = await _mergeService.GetTargetsAsync(taskId, CancellationToken.None); + return new MergeTargetsDto(t.DefaultBranch, t.LocalBranches); + } + catch (KeyNotFoundException) + { + throw new HubException("task not found"); + } + catch (InvalidOperationException ex) + { + throw new HubException(ex.Message); + } + } }