From b5417f6b09bcaee8b6b5a909455673e9b6ddafb2 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Tue, 9 Jun 2026 23:15:05 +0200 Subject: [PATCH] refactor(ui): bring IWorkerClient to parity with WorkerClient Add 16 missing members to IWorkerClient (IsReconnecting, WorkerLogReceivedEvent, PrimeFired, LastApproveTarget, Refresh/RestoreDefaultAgents, UpdateAppSettings, prime schedule CRUD, UpdateList/UpdateListConfig, all worktree ops). Switch all production consumers off the concrete WorkerClient type; only Program.cs/App host still resolves the concrete registration. Update StubWorkerClient and FakeWorkerClient to satisfy the expanded interface. Co-Authored-By: Claude Sonnet 4.6 --- src/ClaudeDo.App/Program.cs | 8 +++---- .../Services/Interfaces/IWorkerClient.cs | 22 +++++++++++++++++++ src/ClaudeDo.Ui/Services/WorkerNotesApi.cs | 4 ++-- .../Services/WorkerPrimeScheduleApi.cs | 4 ++-- .../Islands/DetailsIslandViewModel.cs | 2 +- .../Islands/ListsIslandViewModel.cs | 4 ++-- .../ViewModels/IslandsShellViewModel.cs | 6 ++--- .../Modals/ListSettingsModalViewModel.cs | 4 ++-- .../ViewModels/Modals/MergeModalViewModel.cs | 4 ++-- .../Settings/FilesSettingsTabViewModel.cs | 4 ++-- .../Settings/WorktreesSettingsTabViewModel.cs | 4 ++-- .../Modals/SettingsModalViewModel.cs | 4 ++-- .../Modals/WorktreesOverviewModalViewModel.cs | 4 ++-- tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs | 17 ++++++++++++++ .../UiVm/TasksIslandViewModelPlanningTests.cs | 17 ++++++++++++++ 15 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/ClaudeDo.App/Program.cs b/src/ClaudeDo.App/Program.cs index 3a28694..63d4768 100644 --- a/src/ClaudeDo.App/Program.cs +++ b/src/ClaudeDo.App/Program.cs @@ -134,22 +134,22 @@ sealed class Program sc.AddTransient>(sp => () => sp.GetRequiredService()); sc.AddSingleton>(sp => taskId => new ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel( - sp.GetRequiredService(), taskId)); + sp.GetRequiredService(), taskId)); // Islands shell VMs sc.AddSingleton(sp => new ListsIslandViewModel( sp.GetRequiredService>(), sp, - sp.GetRequiredService())); + sp.GetRequiredService())); sc.AddSingleton(sp => new TasksIslandViewModel( sp.GetRequiredService>(), - sp.GetRequiredService())); + sp.GetRequiredService())); sc.AddSingleton(sp => new DetailsIslandViewModel( sp.GetRequiredService>(), - sp.GetRequiredService(), + sp.GetRequiredService(), sp, sp.GetRequiredService())); sc.AddSingleton(sp => diff --git a/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs b/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs index 28c99b6..5ea64aa 100644 --- a/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs +++ b/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs @@ -8,6 +8,7 @@ namespace ClaudeDo.Ui.Services; public interface IWorkerClient : INotifyPropertyChanged { bool IsConnected { get; } + bool IsReconnecting { get; } event Action? TaskStartedEvent; event Action? TaskFinishedEvent; @@ -17,6 +18,7 @@ public interface IWorkerClient : INotifyPropertyChanged event Action? WorktreeUpdatedEvent; event Action? ListUpdatedEvent; event Action? TaskMessageEvent; + event Action? WorkerLogReceivedEvent; event Action? PrepStartedEvent; event Action? PrepLineEvent; @@ -28,12 +30,18 @@ public interface IWorkerClient : INotifyPropertyChanged event Action? PlanningMergeAbortedEvent; event Action? PlanningCompletedEvent; + event Action? PrimeFired; + + string? LastApproveTarget { get; } + Task WakeQueueAsync(); Task RunNowAsync(string taskId); Task ContinueTaskAsync(string taskId, string followUpPrompt); Task ResetTaskAsync(string taskId); Task CancelTaskAsync(string taskId); Task> GetAgentsAsync(); + Task RefreshAgentsAsync(); + Task RestoreDefaultAgentsAsync(); Task GetListConfigAsync(string listId); Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto); Task SetTaskStatusAsync(string taskId, TaskStatus status); @@ -71,9 +79,23 @@ public interface IWorkerClient : INotifyPropertyChanged event Action? RefineFinishedEvent; Task ClearMyDayAsync(); Task GetAppSettingsAsync(); + Task UpdateAppSettingsAsync(AppSettingsDto dto); Task> GetDailyNotesAsync(DateOnly day); Task AddDailyNoteAsync(DateOnly day, string text); Task UpdateDailyNoteAsync(string id, string text); Task DeleteDailyNoteAsync(string id); Task GetLastPrepLogAsync(); + + Task> GetPrimeSchedulesAsync(); + Task UpsertPrimeScheduleAsync(PrimeScheduleDto dto); + Task DeletePrimeScheduleAsync(Guid id); + + Task UpdateListAsync(UpdateListDto dto); + Task UpdateListConfigAsync(UpdateListConfigDto dto); + + Task CleanupFinishedWorktreesAsync(string? listId = null); + Task ResetAllWorktreesAsync(); + Task> GetWorktreesOverviewAsync(string? listId); + Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState); + Task ForceRemoveWorktreeAsync(string taskId); } diff --git a/src/ClaudeDo.Ui/Services/WorkerNotesApi.cs b/src/ClaudeDo.Ui/Services/WorkerNotesApi.cs index f63768b..d63ddec 100644 --- a/src/ClaudeDo.Ui/Services/WorkerNotesApi.cs +++ b/src/ClaudeDo.Ui/Services/WorkerNotesApi.cs @@ -4,8 +4,8 @@ namespace ClaudeDo.Ui.Services; public sealed class WorkerNotesApi : INotesApi { - private readonly WorkerClient _client; - public WorkerNotesApi(WorkerClient client) => _client = client; + private readonly IWorkerClient _client; + public WorkerNotesApi(IWorkerClient client) => _client = client; public Task> ListAsync(DateOnly day) => _client.GetDailyNotesAsync(day); public Task AddAsync(DateOnly day, string text) => _client.AddDailyNoteAsync(day, text); public Task UpdateAsync(string id, string text) => _client.UpdateDailyNoteAsync(id, text); diff --git a/src/ClaudeDo.Ui/Services/WorkerPrimeScheduleApi.cs b/src/ClaudeDo.Ui/Services/WorkerPrimeScheduleApi.cs index ed72072..b78a06e 100644 --- a/src/ClaudeDo.Ui/Services/WorkerPrimeScheduleApi.cs +++ b/src/ClaudeDo.Ui/Services/WorkerPrimeScheduleApi.cs @@ -2,8 +2,8 @@ namespace ClaudeDo.Ui.Services; public sealed class WorkerPrimeScheduleApi : IPrimeScheduleApi { - private readonly WorkerClient _client; - public WorkerPrimeScheduleApi(WorkerClient client) => _client = client; + private readonly IWorkerClient _client; + public WorkerPrimeScheduleApi(IWorkerClient client) => _client = client; public Task> ListAsync() => _client.GetPrimeSchedulesAsync(); public Task UpsertAsync(PrimeScheduleDto dto) => _client.UpsertPrimeScheduleAsync(dto); public Task DeleteAsync(Guid id) => _client.DeletePrimeScheduleAsync(id); diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs index 480d17f..a314716 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs @@ -548,7 +548,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable // Re-evaluate CanExecute when worker connection flips. _workerPropertyChangedHandler = (_, e) => { - if (e.PropertyName == nameof(WorkerClient.IsConnected)) + if (e.PropertyName == nameof(IWorkerClient.IsConnected)) { EnqueueCommand.NotifyCanExecuteChanged(); DequeueCommand.NotifyCanExecuteChanged(); diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs index 9336028..f5ad258 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs @@ -20,7 +20,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable { private readonly IDbContextFactory _dbFactory; private readonly IServiceProvider? _services; - private readonly WorkerClient? _worker; + private readonly IWorkerClient? _worker; private static readonly TaskListFilterRegistry _filters = new(); public event EventHandler? SelectionChanged; @@ -143,7 +143,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable private readonly EventHandler _langChangedHandler; - public ListsIslandViewModel(IDbContextFactory dbFactory, IServiceProvider? services = null, WorkerClient? worker = null) + public ListsIslandViewModel(IDbContextFactory dbFactory, IServiceProvider? services = null, IWorkerClient? worker = null) { _dbFactory = dbFactory; _services = services; diff --git a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs index c25b2c3..fdf4dd3 100644 --- a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs @@ -20,7 +20,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable public ListsIslandViewModel? Lists { get; } public TasksIslandViewModel? Tasks { get; } public DetailsIslandViewModel? Details { get; } - public WorkerClient? Worker { get; } + public IWorkerClient? Worker { get; } public UpdateCheckService UpdateCheck => _updateCheck; public string ConnectionText => @@ -193,7 +193,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable ListsIslandViewModel lists, TasksIslandViewModel tasks, DetailsIslandViewModel details, - WorkerClient worker, + IWorkerClient worker, UpdateCheckService updateCheck, InstallerLocator installerLocator, WorkerLocator workerLocator, @@ -232,7 +232,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable Details.RequestConflictResolution = RequestConflictResolutionAsync; Worker.PropertyChanged += (_, e) => { - if (e.PropertyName is nameof(WorkerClient.IsConnected) or nameof(WorkerClient.IsReconnecting)) + if (e.PropertyName is nameof(IWorkerClient.IsConnected) or nameof(IWorkerClient.IsReconnecting)) { OnPropertyChanged(nameof(ConnectionText)); OnPropertyChanged(nameof(IsOffline)); diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs index 97e98c1..90c4ee4 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs @@ -12,7 +12,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals; public sealed partial class ListSettingsModalViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; private readonly IDbContextFactory _dbFactory; public string ListId { get; set; } = ""; @@ -50,7 +50,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase public Action? CloseAction { get; set; } - public ListSettingsModalViewModel(WorkerClient worker, IDbContextFactory dbFactory) + public ListSettingsModalViewModel(IWorkerClient worker, IDbContextFactory dbFactory) { _worker = worker; _dbFactory = dbFactory; diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/MergeModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/MergeModalViewModel.cs index fb3f1a6..79d7236 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/MergeModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/MergeModalViewModel.cs @@ -8,7 +8,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals; public sealed partial class MergeModalViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; public string TaskId { get; set; } = ""; public string TaskTitle { get; set; } = ""; @@ -32,7 +32,7 @@ public sealed partial class MergeModalViewModel : ViewModelBase /// close itself after this modal closes. public bool Merged { get; private set; } - public MergeModalViewModel(WorkerClient worker) + public MergeModalViewModel(IWorkerClient worker) { _worker = worker; } diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/Settings/FilesSettingsTabViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/Settings/FilesSettingsTabViewModel.cs index 986ed82..13576ab 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/Settings/FilesSettingsTabViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/Settings/FilesSettingsTabViewModel.cs @@ -9,7 +9,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals.Settings; public sealed partial class FilesSettingsTabViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; [ObservableProperty] private string _statusMessage = ""; [ObservableProperty] private bool _isBusy; @@ -21,7 +21,7 @@ public sealed partial class FilesSettingsTabViewModel : ViewModelBase public string DailyPrepPromptPath { get; } = PromptFiles.PathFor(PromptKind.DailyPrep); public string WeeklyReportPromptPath { get; } = PromptFiles.PathFor(PromptKind.WeeklyReport); - public FilesSettingsTabViewModel(WorkerClient worker) => _worker = worker; + public FilesSettingsTabViewModel(IWorkerClient worker) => _worker = worker; [RelayCommand] private async Task RestoreDefaultAgents() diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/Settings/WorktreesSettingsTabViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/Settings/WorktreesSettingsTabViewModel.cs index 277d345..b62376b 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/Settings/WorktreesSettingsTabViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/Settings/WorktreesSettingsTabViewModel.cs @@ -8,7 +8,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals.Settings; public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; [ObservableProperty] private string _worktreeStrategy = "sibling"; [ObservableProperty] private string? _centralWorktreeRoot; @@ -21,7 +21,7 @@ public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase public IReadOnlyList WorktreeStrategies { get; } = new[] { "sibling", "central" }; - public WorktreesSettingsTabViewModel(WorkerClient worker) => _worker = worker; + public WorktreesSettingsTabViewModel(IWorkerClient worker) => _worker = worker; public string? Validate() { diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/SettingsModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/SettingsModalViewModel.cs index 827981f..58477ae 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/SettingsModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/SettingsModalViewModel.cs @@ -11,7 +11,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals; public sealed partial class SettingsModalViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; public GeneralSettingsTabViewModel General { get; } public WorktreesSettingsTabViewModel Worktrees { get; } @@ -24,7 +24,7 @@ public sealed partial class SettingsModalViewModel : ViewModelBase public Action? CloseAction { get; set; } - public SettingsModalViewModel(WorkerClient worker, PrimeClaudeTabViewModel prime, + public SettingsModalViewModel(IWorkerClient worker, PrimeClaudeTabViewModel prime, ILocalizer localizer, AppSettings appSettings) { _worker = worker; diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/WorktreesOverviewModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/WorktreesOverviewModalViewModel.cs index aa92c6a..ffa90df 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/WorktreesOverviewModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/WorktreesOverviewModalViewModel.cs @@ -60,7 +60,7 @@ public sealed partial class WorktreesGroupViewModel : ViewModelBase public sealed partial class WorktreesOverviewModalViewModel : ViewModelBase { - private readonly WorkerClient _worker; + private readonly IWorkerClient _worker; private readonly Func _diffVmFactory; [ObservableProperty] private string? _listIdFilter; @@ -89,7 +89,7 @@ public sealed partial class WorktreesOverviewModalViewModel : ViewModelBase public Func? ResolveMergeVm { get; set; } public Func? ShowMergeAction { get; set; } - public WorktreesOverviewModalViewModel(WorkerClient worker, Func diffVmFactory) + public WorktreesOverviewModalViewModel(IWorkerClient worker, Func diffVmFactory) { _worker = worker; _diffVmFactory = diffVmFactory; diff --git a/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs b/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs index d1a5468..e331be9 100644 --- a/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs +++ b/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs @@ -22,6 +22,7 @@ public abstract class StubWorkerClient : IWorkerClient public event Action? WorktreeUpdatedEvent; public event Action? ListUpdatedEvent; public event Action? TaskMessageEvent; + public event Action? WorkerLogReceivedEvent; public event Action? PrepStartedEvent; public event Action? PrepLineEvent; public event Action? PrepFinishedEvent; @@ -32,6 +33,7 @@ public abstract class StubWorkerClient : IWorkerClient public event Action>? PlanningMergeConflictEvent; public event Action? PlanningMergeAbortedEvent; public event Action? PlanningCompletedEvent; + public event Action? PrimeFired; #pragma warning restore CS0067 public int ClearMyDayCalls { get; private set; } @@ -42,6 +44,8 @@ public abstract class StubWorkerClient : IWorkerClient public void RaisePrepFinished(bool ok) => PrepFinishedEvent?.Invoke(ok); public virtual bool IsConnected => false; + public virtual bool IsReconnecting => false; + public virtual string? LastApproveTarget => null; public virtual Task WakeQueueAsync() => Task.CompletedTask; public virtual Task RunNowAsync(string taskId) => Task.CompletedTask; @@ -49,6 +53,8 @@ public abstract class StubWorkerClient : IWorkerClient public virtual Task ResetTaskAsync(string taskId) => Task.CompletedTask; public virtual Task CancelTaskAsync(string taskId) => Task.CompletedTask; public virtual Task> GetAgentsAsync() => Task.FromResult(new List()); + public virtual Task RefreshAgentsAsync() => Task.CompletedTask; + public virtual Task RestoreDefaultAgentsAsync() => Task.FromResult(null); public virtual Task GetListConfigAsync(string listId) => Task.FromResult(null); public virtual Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask; public virtual Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask; @@ -83,6 +89,17 @@ public abstract class StubWorkerClient : IWorkerClient public virtual Task RunDailyPrepNowAsync() { RunDailyPrepNowCalls++; return Task.FromResult(false); } public virtual Task ClearMyDayAsync() { ClearMyDayCalls++; return Task.CompletedTask; } public virtual Task GetAppSettingsAsync() => Task.FromResult(null); + public virtual Task UpdateAppSettingsAsync(AppSettingsDto dto) => Task.CompletedTask; + public virtual Task> GetPrimeSchedulesAsync() => Task.FromResult(new List()); + public virtual Task UpsertPrimeScheduleAsync(PrimeScheduleDto dto) => Task.FromResult(null); + public virtual Task DeletePrimeScheduleAsync(Guid id) => Task.CompletedTask; + public virtual Task UpdateListAsync(UpdateListDto dto) => Task.CompletedTask; + public virtual Task UpdateListConfigAsync(UpdateListConfigDto dto) => Task.CompletedTask; + public virtual Task CleanupFinishedWorktreesAsync(string? listId = null) => Task.FromResult(null); + public virtual Task ResetAllWorktreesAsync() => Task.FromResult(null); + public virtual Task> GetWorktreesOverviewAsync(string? listId) => Task.FromResult(new List()); + public virtual Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState) => Task.FromResult((true, (string?)null)); + public virtual Task ForceRemoveWorktreeAsync(string taskId) => Task.FromResult(null); public virtual Task> GetDailyNotesAsync(DateOnly day) => Task.FromResult(new List()); public virtual Task AddDailyNoteAsync(DateOnly day, string text) => Task.FromResult(null); public virtual Task UpdateDailyNoteAsync(string id, string text) => Task.CompletedTask; diff --git a/tests/ClaudeDo.Worker.Tests/UiVm/TasksIslandViewModelPlanningTests.cs b/tests/ClaudeDo.Worker.Tests/UiVm/TasksIslandViewModelPlanningTests.cs index ae8e907..320f93e 100644 --- a/tests/ClaudeDo.Worker.Tests/UiVm/TasksIslandViewModelPlanningTests.cs +++ b/tests/ClaudeDo.Worker.Tests/UiVm/TasksIslandViewModelPlanningTests.cs @@ -21,6 +21,8 @@ sealed class FakeWorkerClient : IWorkerClient public int WakeQueueCalls { get; private set; } public bool IsConnected => false; + public bool IsReconnecting => false; + public string? LastApproveTarget => null; #pragma warning disable CS0067 // events required by IWorkerClient but not exercised by this fake public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged; public event Action? TaskStartedEvent; @@ -30,6 +32,7 @@ sealed class FakeWorkerClient : IWorkerClient public event Action? WorktreeUpdatedEvent; public event Action? ListUpdatedEvent; public event Action? TaskMessageEvent; + public event Action? WorkerLogReceivedEvent; public void RaiseTaskUpdated(string taskId) => TaskUpdatedEvent?.Invoke(taskId); public void RaiseWorktreeUpdated(string taskId) => WorktreeUpdatedEvent?.Invoke(taskId); public void RaiseTaskMessage(string taskId, string line) => TaskMessageEvent?.Invoke(taskId, line); @@ -39,6 +42,8 @@ sealed class FakeWorkerClient : IWorkerClient public Task ResetTaskAsync(string taskId) => Task.CompletedTask; public Task CancelTaskAsync(string taskId) => Task.CompletedTask; public Task> GetAgentsAsync() => Task.FromResult(new List()); + public Task RefreshAgentsAsync() => Task.CompletedTask; + public Task RestoreDefaultAgentsAsync() => Task.FromResult(null); public Task GetListConfigAsync(string listId) => Task.FromResult(null); public Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask; public Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask; @@ -76,6 +81,7 @@ sealed class FakeWorkerClient : IWorkerClient public event Action>? PlanningMergeConflictEvent; public event Action? PlanningMergeAbortedEvent; public event Action? PlanningCompletedEvent; + public event Action? PrimeFired; #pragma warning restore CS0067 public Task GetMergeTargetsAsync(string taskId) => Task.FromResult(null); @@ -85,6 +91,17 @@ sealed class FakeWorkerClient : IWorkerClient public Task AbortPlanningMergeAsync(string planningTaskId) => Task.CompletedTask; public Task GetAppSettingsAsync() => Task.FromResult(null); + public Task UpdateAppSettingsAsync(AppSettingsDto dto) => Task.CompletedTask; + public Task> GetPrimeSchedulesAsync() => Task.FromResult(new List()); + public Task UpsertPrimeScheduleAsync(PrimeScheduleDto dto) => Task.FromResult(null); + public Task DeletePrimeScheduleAsync(Guid id) => Task.CompletedTask; + public Task UpdateListAsync(UpdateListDto dto) => Task.CompletedTask; + public Task UpdateListConfigAsync(UpdateListConfigDto dto) => Task.CompletedTask; + public Task CleanupFinishedWorktreesAsync(string? listId = null) => Task.FromResult(null); + public Task ResetAllWorktreesAsync() => Task.FromResult(null); + public Task> GetWorktreesOverviewAsync(string? listId) => Task.FromResult(new List()); + public Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState) => Task.FromResult((true, (string?)null)); + public Task ForceRemoveWorktreeAsync(string taskId) => Task.FromResult(null); public Task GetWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(null); public Task GenerateWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(""); public Task RunDailyPrepNowAsync() => Task.FromResult(false);