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 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-06-09 23:15:05 +02:00
parent ddeded988a
commit b5417f6b09
15 changed files with 82 additions and 26 deletions

View File

@@ -134,22 +134,22 @@ sealed class Program
sc.AddTransient<Func<WeeklyReportModalViewModel>>(sp => () => sp.GetRequiredService<WeeklyReportModalViewModel>()); sc.AddTransient<Func<WeeklyReportModalViewModel>>(sp => () => sp.GetRequiredService<WeeklyReportModalViewModel>());
sc.AddSingleton<Func<string, ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel>>(sp => sc.AddSingleton<Func<string, ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel>>(sp =>
taskId => new ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel( taskId => new ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel(
sp.GetRequiredService<WorkerClient>(), taskId)); sp.GetRequiredService<IWorkerClient>(), taskId));
// Islands shell VMs // Islands shell VMs
sc.AddSingleton<ListsIslandViewModel>(sp => sc.AddSingleton<ListsIslandViewModel>(sp =>
new ListsIslandViewModel( new ListsIslandViewModel(
sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(), sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(),
sp, sp,
sp.GetRequiredService<WorkerClient>())); sp.GetRequiredService<IWorkerClient>()));
sc.AddSingleton<TasksIslandViewModel>(sp => sc.AddSingleton<TasksIslandViewModel>(sp =>
new TasksIslandViewModel( new TasksIslandViewModel(
sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(), sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(),
sp.GetRequiredService<WorkerClient>())); sp.GetRequiredService<IWorkerClient>()));
sc.AddSingleton<DetailsIslandViewModel>(sp => sc.AddSingleton<DetailsIslandViewModel>(sp =>
new DetailsIslandViewModel( new DetailsIslandViewModel(
sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(), sp.GetRequiredService<IDbContextFactory<ClaudeDoDbContext>>(),
sp.GetRequiredService<WorkerClient>(), sp.GetRequiredService<IWorkerClient>(),
sp, sp,
sp.GetRequiredService<INotesApi>())); sp.GetRequiredService<INotesApi>()));
sc.AddSingleton<IslandsShellViewModel>(sp => sc.AddSingleton<IslandsShellViewModel>(sp =>

View File

@@ -8,6 +8,7 @@ namespace ClaudeDo.Ui.Services;
public interface IWorkerClient : INotifyPropertyChanged public interface IWorkerClient : INotifyPropertyChanged
{ {
bool IsConnected { get; } bool IsConnected { get; }
bool IsReconnecting { get; }
event Action<string, string, DateTime>? TaskStartedEvent; event Action<string, string, DateTime>? TaskStartedEvent;
event Action<string, string, string, DateTime>? TaskFinishedEvent; event Action<string, string, string, DateTime>? TaskFinishedEvent;
@@ -17,6 +18,7 @@ public interface IWorkerClient : INotifyPropertyChanged
event Action<string>? WorktreeUpdatedEvent; event Action<string>? WorktreeUpdatedEvent;
event Action<string>? ListUpdatedEvent; event Action<string>? ListUpdatedEvent;
event Action<string, string>? TaskMessageEvent; event Action<string, string>? TaskMessageEvent;
event Action<WorkerLogEntry>? WorkerLogReceivedEvent;
event Action? PrepStartedEvent; event Action? PrepStartedEvent;
event Action<string>? PrepLineEvent; event Action<string>? PrepLineEvent;
@@ -28,12 +30,18 @@ public interface IWorkerClient : INotifyPropertyChanged
event Action<string>? PlanningMergeAbortedEvent; event Action<string>? PlanningMergeAbortedEvent;
event Action<string>? PlanningCompletedEvent; event Action<string>? PlanningCompletedEvent;
event Action<PrimeFiredEvent>? PrimeFired;
string? LastApproveTarget { get; }
Task WakeQueueAsync(); Task WakeQueueAsync();
Task RunNowAsync(string taskId); Task RunNowAsync(string taskId);
Task ContinueTaskAsync(string taskId, string followUpPrompt); Task ContinueTaskAsync(string taskId, string followUpPrompt);
Task ResetTaskAsync(string taskId); Task ResetTaskAsync(string taskId);
Task CancelTaskAsync(string taskId); Task CancelTaskAsync(string taskId);
Task<List<AgentInfo>> GetAgentsAsync(); Task<List<AgentInfo>> GetAgentsAsync();
Task RefreshAgentsAsync();
Task<SeedResultDto?> RestoreDefaultAgentsAsync();
Task<ListConfigDto?> GetListConfigAsync(string listId); Task<ListConfigDto?> GetListConfigAsync(string listId);
Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto); Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto);
Task SetTaskStatusAsync(string taskId, TaskStatus status); Task SetTaskStatusAsync(string taskId, TaskStatus status);
@@ -71,9 +79,23 @@ public interface IWorkerClient : INotifyPropertyChanged
event Action<string, bool, string?>? RefineFinishedEvent; event Action<string, bool, string?>? RefineFinishedEvent;
Task ClearMyDayAsync(); Task ClearMyDayAsync();
Task<AppSettingsDto?> GetAppSettingsAsync(); Task<AppSettingsDto?> GetAppSettingsAsync();
Task UpdateAppSettingsAsync(AppSettingsDto dto);
Task<List<DailyNoteDto>> GetDailyNotesAsync(DateOnly day); Task<List<DailyNoteDto>> GetDailyNotesAsync(DateOnly day);
Task<DailyNoteDto?> AddDailyNoteAsync(DateOnly day, string text); Task<DailyNoteDto?> AddDailyNoteAsync(DateOnly day, string text);
Task UpdateDailyNoteAsync(string id, string text); Task UpdateDailyNoteAsync(string id, string text);
Task DeleteDailyNoteAsync(string id); Task DeleteDailyNoteAsync(string id);
Task<string> GetLastPrepLogAsync(); Task<string> GetLastPrepLogAsync();
Task<List<PrimeScheduleDto>> GetPrimeSchedulesAsync();
Task<PrimeScheduleDto?> UpsertPrimeScheduleAsync(PrimeScheduleDto dto);
Task DeletePrimeScheduleAsync(Guid id);
Task UpdateListAsync(UpdateListDto dto);
Task UpdateListConfigAsync(UpdateListConfigDto dto);
Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null);
Task<WorktreeResetDto?> ResetAllWorktreesAsync();
Task<List<WorktreeOverviewDto>> GetWorktreesOverviewAsync(string? listId);
Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState);
Task<ForceRemoveResultDto?> ForceRemoveWorktreeAsync(string taskId);
} }

View File

@@ -4,8 +4,8 @@ namespace ClaudeDo.Ui.Services;
public sealed class WorkerNotesApi : INotesApi public sealed class WorkerNotesApi : INotesApi
{ {
private readonly WorkerClient _client; private readonly IWorkerClient _client;
public WorkerNotesApi(WorkerClient client) => _client = client; public WorkerNotesApi(IWorkerClient client) => _client = client;
public Task<List<DailyNoteDto>> ListAsync(DateOnly day) => _client.GetDailyNotesAsync(day); public Task<List<DailyNoteDto>> ListAsync(DateOnly day) => _client.GetDailyNotesAsync(day);
public Task<DailyNoteDto?> AddAsync(DateOnly day, string text) => _client.AddDailyNoteAsync(day, text); public Task<DailyNoteDto?> AddAsync(DateOnly day, string text) => _client.AddDailyNoteAsync(day, text);
public Task UpdateAsync(string id, string text) => _client.UpdateDailyNoteAsync(id, text); public Task UpdateAsync(string id, string text) => _client.UpdateDailyNoteAsync(id, text);

View File

@@ -2,8 +2,8 @@ namespace ClaudeDo.Ui.Services;
public sealed class WorkerPrimeScheduleApi : IPrimeScheduleApi public sealed class WorkerPrimeScheduleApi : IPrimeScheduleApi
{ {
private readonly WorkerClient _client; private readonly IWorkerClient _client;
public WorkerPrimeScheduleApi(WorkerClient client) => _client = client; public WorkerPrimeScheduleApi(IWorkerClient client) => _client = client;
public Task<List<PrimeScheduleDto>> ListAsync() => _client.GetPrimeSchedulesAsync(); public Task<List<PrimeScheduleDto>> ListAsync() => _client.GetPrimeSchedulesAsync();
public Task<PrimeScheduleDto?> UpsertAsync(PrimeScheduleDto dto) => _client.UpsertPrimeScheduleAsync(dto); public Task<PrimeScheduleDto?> UpsertAsync(PrimeScheduleDto dto) => _client.UpsertPrimeScheduleAsync(dto);
public Task DeleteAsync(Guid id) => _client.DeletePrimeScheduleAsync(id); public Task DeleteAsync(Guid id) => _client.DeletePrimeScheduleAsync(id);

View File

@@ -548,7 +548,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
// Re-evaluate CanExecute when worker connection flips. // Re-evaluate CanExecute when worker connection flips.
_workerPropertyChangedHandler = (_, e) => _workerPropertyChangedHandler = (_, e) =>
{ {
if (e.PropertyName == nameof(WorkerClient.IsConnected)) if (e.PropertyName == nameof(IWorkerClient.IsConnected))
{ {
EnqueueCommand.NotifyCanExecuteChanged(); EnqueueCommand.NotifyCanExecuteChanged();
DequeueCommand.NotifyCanExecuteChanged(); DequeueCommand.NotifyCanExecuteChanged();

View File

@@ -20,7 +20,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable
{ {
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory; private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
private readonly IServiceProvider? _services; private readonly IServiceProvider? _services;
private readonly WorkerClient? _worker; private readonly IWorkerClient? _worker;
private static readonly TaskListFilterRegistry _filters = new(); private static readonly TaskListFilterRegistry _filters = new();
public event EventHandler? SelectionChanged; public event EventHandler? SelectionChanged;
@@ -143,7 +143,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable
private readonly EventHandler _langChangedHandler; private readonly EventHandler _langChangedHandler;
public ListsIslandViewModel(IDbContextFactory<ClaudeDoDbContext> dbFactory, IServiceProvider? services = null, WorkerClient? worker = null) public ListsIslandViewModel(IDbContextFactory<ClaudeDoDbContext> dbFactory, IServiceProvider? services = null, IWorkerClient? worker = null)
{ {
_dbFactory = dbFactory; _dbFactory = dbFactory;
_services = services; _services = services;

View File

@@ -20,7 +20,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
public ListsIslandViewModel? Lists { get; } public ListsIslandViewModel? Lists { get; }
public TasksIslandViewModel? Tasks { get; } public TasksIslandViewModel? Tasks { get; }
public DetailsIslandViewModel? Details { get; } public DetailsIslandViewModel? Details { get; }
public WorkerClient? Worker { get; } public IWorkerClient? Worker { get; }
public UpdateCheckService UpdateCheck => _updateCheck; public UpdateCheckService UpdateCheck => _updateCheck;
public string ConnectionText => public string ConnectionText =>
@@ -193,7 +193,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
ListsIslandViewModel lists, ListsIslandViewModel lists,
TasksIslandViewModel tasks, TasksIslandViewModel tasks,
DetailsIslandViewModel details, DetailsIslandViewModel details,
WorkerClient worker, IWorkerClient worker,
UpdateCheckService updateCheck, UpdateCheckService updateCheck,
InstallerLocator installerLocator, InstallerLocator installerLocator,
WorkerLocator workerLocator, WorkerLocator workerLocator,
@@ -232,7 +232,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
Details.RequestConflictResolution = RequestConflictResolutionAsync; Details.RequestConflictResolution = RequestConflictResolutionAsync;
Worker.PropertyChanged += (_, e) => 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(ConnectionText));
OnPropertyChanged(nameof(IsOffline)); OnPropertyChanged(nameof(IsOffline));

View File

@@ -12,7 +12,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals;
public sealed partial class ListSettingsModalViewModel : ViewModelBase public sealed partial class ListSettingsModalViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory; private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
public string ListId { get; set; } = ""; public string ListId { get; set; } = "";
@@ -50,7 +50,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
public Action? CloseAction { get; set; } public Action? CloseAction { get; set; }
public ListSettingsModalViewModel(WorkerClient worker, IDbContextFactory<ClaudeDoDbContext> dbFactory) public ListSettingsModalViewModel(IWorkerClient worker, IDbContextFactory<ClaudeDoDbContext> dbFactory)
{ {
_worker = worker; _worker = worker;
_dbFactory = dbFactory; _dbFactory = dbFactory;

View File

@@ -8,7 +8,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals;
public sealed partial class MergeModalViewModel : ViewModelBase public sealed partial class MergeModalViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
public string TaskId { get; set; } = ""; public string TaskId { get; set; } = "";
public string TaskTitle { get; set; } = ""; public string TaskTitle { get; set; } = "";
@@ -32,7 +32,7 @@ public sealed partial class MergeModalViewModel : ViewModelBase
/// close itself after this modal closes. /// close itself after this modal closes.
public bool Merged { get; private set; } public bool Merged { get; private set; }
public MergeModalViewModel(WorkerClient worker) public MergeModalViewModel(IWorkerClient worker)
{ {
_worker = worker; _worker = worker;
} }

View File

@@ -9,7 +9,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
public sealed partial class FilesSettingsTabViewModel : ViewModelBase public sealed partial class FilesSettingsTabViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
[ObservableProperty] private string _statusMessage = ""; [ObservableProperty] private string _statusMessage = "";
[ObservableProperty] private bool _isBusy; [ObservableProperty] private bool _isBusy;
@@ -21,7 +21,7 @@ public sealed partial class FilesSettingsTabViewModel : ViewModelBase
public string DailyPrepPromptPath { get; } = PromptFiles.PathFor(PromptKind.DailyPrep); public string DailyPrepPromptPath { get; } = PromptFiles.PathFor(PromptKind.DailyPrep);
public string WeeklyReportPromptPath { get; } = PromptFiles.PathFor(PromptKind.WeeklyReport); public string WeeklyReportPromptPath { get; } = PromptFiles.PathFor(PromptKind.WeeklyReport);
public FilesSettingsTabViewModel(WorkerClient worker) => _worker = worker; public FilesSettingsTabViewModel(IWorkerClient worker) => _worker = worker;
[RelayCommand] [RelayCommand]
private async Task RestoreDefaultAgents() private async Task RestoreDefaultAgents()

View File

@@ -8,7 +8,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
[ObservableProperty] private string _worktreeStrategy = "sibling"; [ObservableProperty] private string _worktreeStrategy = "sibling";
[ObservableProperty] private string? _centralWorktreeRoot; [ObservableProperty] private string? _centralWorktreeRoot;
@@ -21,7 +21,7 @@ public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase
public IReadOnlyList<string> WorktreeStrategies { get; } = new[] { "sibling", "central" }; public IReadOnlyList<string> WorktreeStrategies { get; } = new[] { "sibling", "central" };
public WorktreesSettingsTabViewModel(WorkerClient worker) => _worker = worker; public WorktreesSettingsTabViewModel(IWorkerClient worker) => _worker = worker;
public string? Validate() public string? Validate()
{ {

View File

@@ -11,7 +11,7 @@ namespace ClaudeDo.Ui.ViewModels.Modals;
public sealed partial class SettingsModalViewModel : ViewModelBase public sealed partial class SettingsModalViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
public GeneralSettingsTabViewModel General { get; } public GeneralSettingsTabViewModel General { get; }
public WorktreesSettingsTabViewModel Worktrees { get; } public WorktreesSettingsTabViewModel Worktrees { get; }
@@ -24,7 +24,7 @@ public sealed partial class SettingsModalViewModel : ViewModelBase
public Action? CloseAction { get; set; } public Action? CloseAction { get; set; }
public SettingsModalViewModel(WorkerClient worker, PrimeClaudeTabViewModel prime, public SettingsModalViewModel(IWorkerClient worker, PrimeClaudeTabViewModel prime,
ILocalizer localizer, AppSettings appSettings) ILocalizer localizer, AppSettings appSettings)
{ {
_worker = worker; _worker = worker;

View File

@@ -60,7 +60,7 @@ public sealed partial class WorktreesGroupViewModel : ViewModelBase
public sealed partial class WorktreesOverviewModalViewModel : ViewModelBase public sealed partial class WorktreesOverviewModalViewModel : ViewModelBase
{ {
private readonly WorkerClient _worker; private readonly IWorkerClient _worker;
private readonly Func<WorktreeModalViewModel> _diffVmFactory; private readonly Func<WorktreeModalViewModel> _diffVmFactory;
[ObservableProperty] private string? _listIdFilter; [ObservableProperty] private string? _listIdFilter;
@@ -89,7 +89,7 @@ public sealed partial class WorktreesOverviewModalViewModel : ViewModelBase
public Func<MergeModalViewModel>? ResolveMergeVm { get; set; } public Func<MergeModalViewModel>? ResolveMergeVm { get; set; }
public Func<MergeModalViewModel, Task>? ShowMergeAction { get; set; } public Func<MergeModalViewModel, Task>? ShowMergeAction { get; set; }
public WorktreesOverviewModalViewModel(WorkerClient worker, Func<WorktreeModalViewModel> diffVmFactory) public WorktreesOverviewModalViewModel(IWorkerClient worker, Func<WorktreeModalViewModel> diffVmFactory)
{ {
_worker = worker; _worker = worker;
_diffVmFactory = diffVmFactory; _diffVmFactory = diffVmFactory;

View File

@@ -22,6 +22,7 @@ public abstract class StubWorkerClient : IWorkerClient
public event Action<string>? WorktreeUpdatedEvent; public event Action<string>? WorktreeUpdatedEvent;
public event Action<string>? ListUpdatedEvent; public event Action<string>? ListUpdatedEvent;
public event Action<string, string>? TaskMessageEvent; public event Action<string, string>? TaskMessageEvent;
public event Action<WorkerLogEntry>? WorkerLogReceivedEvent;
public event Action? PrepStartedEvent; public event Action? PrepStartedEvent;
public event Action<string>? PrepLineEvent; public event Action<string>? PrepLineEvent;
public event Action<bool>? PrepFinishedEvent; public event Action<bool>? PrepFinishedEvent;
@@ -32,6 +33,7 @@ public abstract class StubWorkerClient : IWorkerClient
public event Action<string, string, IReadOnlyList<string>>? PlanningMergeConflictEvent; public event Action<string, string, IReadOnlyList<string>>? PlanningMergeConflictEvent;
public event Action<string>? PlanningMergeAbortedEvent; public event Action<string>? PlanningMergeAbortedEvent;
public event Action<string>? PlanningCompletedEvent; public event Action<string>? PlanningCompletedEvent;
public event Action<PrimeFiredEvent>? PrimeFired;
#pragma warning restore CS0067 #pragma warning restore CS0067
public int ClearMyDayCalls { get; private set; } public int ClearMyDayCalls { get; private set; }
@@ -42,6 +44,8 @@ public abstract class StubWorkerClient : IWorkerClient
public void RaisePrepFinished(bool ok) => PrepFinishedEvent?.Invoke(ok); public void RaisePrepFinished(bool ok) => PrepFinishedEvent?.Invoke(ok);
public virtual bool IsConnected => false; public virtual bool IsConnected => false;
public virtual bool IsReconnecting => false;
public virtual string? LastApproveTarget => null;
public virtual Task WakeQueueAsync() => Task.CompletedTask; public virtual Task WakeQueueAsync() => Task.CompletedTask;
public virtual Task RunNowAsync(string taskId) => 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 ResetTaskAsync(string taskId) => Task.CompletedTask;
public virtual Task CancelTaskAsync(string taskId) => Task.CompletedTask; public virtual Task CancelTaskAsync(string taskId) => Task.CompletedTask;
public virtual Task<List<AgentInfo>> GetAgentsAsync() => Task.FromResult(new List<AgentInfo>()); public virtual Task<List<AgentInfo>> GetAgentsAsync() => Task.FromResult(new List<AgentInfo>());
public virtual Task RefreshAgentsAsync() => Task.CompletedTask;
public virtual Task<SeedResultDto?> RestoreDefaultAgentsAsync() => Task.FromResult<SeedResultDto?>(null);
public virtual Task<ListConfigDto?> GetListConfigAsync(string listId) => Task.FromResult<ListConfigDto?>(null); public virtual Task<ListConfigDto?> GetListConfigAsync(string listId) => Task.FromResult<ListConfigDto?>(null);
public virtual Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask; public virtual Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask;
public virtual Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask; public virtual Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask;
@@ -83,6 +89,17 @@ public abstract class StubWorkerClient : IWorkerClient
public virtual Task<bool> RunDailyPrepNowAsync() { RunDailyPrepNowCalls++; return Task.FromResult(false); } public virtual Task<bool> RunDailyPrepNowAsync() { RunDailyPrepNowCalls++; return Task.FromResult(false); }
public virtual Task ClearMyDayAsync() { ClearMyDayCalls++; return Task.CompletedTask; } public virtual Task ClearMyDayAsync() { ClearMyDayCalls++; return Task.CompletedTask; }
public virtual Task<AppSettingsDto?> GetAppSettingsAsync() => Task.FromResult<AppSettingsDto?>(null); public virtual Task<AppSettingsDto?> GetAppSettingsAsync() => Task.FromResult<AppSettingsDto?>(null);
public virtual Task UpdateAppSettingsAsync(AppSettingsDto dto) => Task.CompletedTask;
public virtual Task<List<PrimeScheduleDto>> GetPrimeSchedulesAsync() => Task.FromResult(new List<PrimeScheduleDto>());
public virtual Task<PrimeScheduleDto?> UpsertPrimeScheduleAsync(PrimeScheduleDto dto) => Task.FromResult<PrimeScheduleDto?>(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<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null) => Task.FromResult<WorktreeCleanupDto?>(null);
public virtual Task<WorktreeResetDto?> ResetAllWorktreesAsync() => Task.FromResult<WorktreeResetDto?>(null);
public virtual Task<List<WorktreeOverviewDto>> GetWorktreesOverviewAsync(string? listId) => Task.FromResult(new List<WorktreeOverviewDto>());
public virtual Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState) => Task.FromResult((true, (string?)null));
public virtual Task<ForceRemoveResultDto?> ForceRemoveWorktreeAsync(string taskId) => Task.FromResult<ForceRemoveResultDto?>(null);
public virtual Task<List<DailyNoteDto>> GetDailyNotesAsync(DateOnly day) => Task.FromResult(new List<DailyNoteDto>()); public virtual Task<List<DailyNoteDto>> GetDailyNotesAsync(DateOnly day) => Task.FromResult(new List<DailyNoteDto>());
public virtual Task<DailyNoteDto?> AddDailyNoteAsync(DateOnly day, string text) => Task.FromResult<DailyNoteDto?>(null); public virtual Task<DailyNoteDto?> AddDailyNoteAsync(DateOnly day, string text) => Task.FromResult<DailyNoteDto?>(null);
public virtual Task UpdateDailyNoteAsync(string id, string text) => Task.CompletedTask; public virtual Task UpdateDailyNoteAsync(string id, string text) => Task.CompletedTask;

View File

@@ -21,6 +21,8 @@ sealed class FakeWorkerClient : IWorkerClient
public int WakeQueueCalls { get; private set; } public int WakeQueueCalls { get; private set; }
public bool IsConnected => false; 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 #pragma warning disable CS0067 // events required by IWorkerClient but not exercised by this fake
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged; public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
public event Action<string, string, DateTime>? TaskStartedEvent; public event Action<string, string, DateTime>? TaskStartedEvent;
@@ -30,6 +32,7 @@ sealed class FakeWorkerClient : IWorkerClient
public event Action<string>? WorktreeUpdatedEvent; public event Action<string>? WorktreeUpdatedEvent;
public event Action<string>? ListUpdatedEvent; public event Action<string>? ListUpdatedEvent;
public event Action<string, string>? TaskMessageEvent; public event Action<string, string>? TaskMessageEvent;
public event Action<WorkerLogEntry>? WorkerLogReceivedEvent;
public void RaiseTaskUpdated(string taskId) => TaskUpdatedEvent?.Invoke(taskId); public void RaiseTaskUpdated(string taskId) => TaskUpdatedEvent?.Invoke(taskId);
public void RaiseWorktreeUpdated(string taskId) => WorktreeUpdatedEvent?.Invoke(taskId); public void RaiseWorktreeUpdated(string taskId) => WorktreeUpdatedEvent?.Invoke(taskId);
public void RaiseTaskMessage(string taskId, string line) => TaskMessageEvent?.Invoke(taskId, line); 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 ResetTaskAsync(string taskId) => Task.CompletedTask;
public Task CancelTaskAsync(string taskId) => Task.CompletedTask; public Task CancelTaskAsync(string taskId) => Task.CompletedTask;
public Task<List<AgentInfo>> GetAgentsAsync() => Task.FromResult(new List<AgentInfo>()); public Task<List<AgentInfo>> GetAgentsAsync() => Task.FromResult(new List<AgentInfo>());
public Task RefreshAgentsAsync() => Task.CompletedTask;
public Task<SeedResultDto?> RestoreDefaultAgentsAsync() => Task.FromResult<SeedResultDto?>(null);
public Task<ListConfigDto?> GetListConfigAsync(string listId) => Task.FromResult<ListConfigDto?>(null); public Task<ListConfigDto?> GetListConfigAsync(string listId) => Task.FromResult<ListConfigDto?>(null);
public Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask; public Task UpdateTaskAgentSettingsAsync(UpdateTaskAgentSettingsDto dto) => Task.CompletedTask;
public Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask; public Task SetTaskStatusAsync(string taskId, TaskStatus status) => Task.CompletedTask;
@@ -76,6 +81,7 @@ sealed class FakeWorkerClient : IWorkerClient
public event Action<string, string, IReadOnlyList<string>>? PlanningMergeConflictEvent; public event Action<string, string, IReadOnlyList<string>>? PlanningMergeConflictEvent;
public event Action<string>? PlanningMergeAbortedEvent; public event Action<string>? PlanningMergeAbortedEvent;
public event Action<string>? PlanningCompletedEvent; public event Action<string>? PlanningCompletedEvent;
public event Action<PrimeFiredEvent>? PrimeFired;
#pragma warning restore CS0067 #pragma warning restore CS0067
public Task<MergeTargetsDto?> GetMergeTargetsAsync(string taskId) => Task.FromResult<MergeTargetsDto?>(null); public Task<MergeTargetsDto?> GetMergeTargetsAsync(string taskId) => Task.FromResult<MergeTargetsDto?>(null);
@@ -85,6 +91,17 @@ sealed class FakeWorkerClient : IWorkerClient
public Task AbortPlanningMergeAsync(string planningTaskId) => Task.CompletedTask; public Task AbortPlanningMergeAsync(string planningTaskId) => Task.CompletedTask;
public Task<AppSettingsDto?> GetAppSettingsAsync() => Task.FromResult<AppSettingsDto?>(null); public Task<AppSettingsDto?> GetAppSettingsAsync() => Task.FromResult<AppSettingsDto?>(null);
public Task UpdateAppSettingsAsync(AppSettingsDto dto) => Task.CompletedTask;
public Task<List<PrimeScheduleDto>> GetPrimeSchedulesAsync() => Task.FromResult(new List<PrimeScheduleDto>());
public Task<PrimeScheduleDto?> UpsertPrimeScheduleAsync(PrimeScheduleDto dto) => Task.FromResult<PrimeScheduleDto?>(null);
public Task DeletePrimeScheduleAsync(Guid id) => Task.CompletedTask;
public Task UpdateListAsync(UpdateListDto dto) => Task.CompletedTask;
public Task UpdateListConfigAsync(UpdateListConfigDto dto) => Task.CompletedTask;
public Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null) => Task.FromResult<WorktreeCleanupDto?>(null);
public Task<WorktreeResetDto?> ResetAllWorktreesAsync() => Task.FromResult<WorktreeResetDto?>(null);
public Task<List<WorktreeOverviewDto>> GetWorktreesOverviewAsync(string? listId) => Task.FromResult(new List<WorktreeOverviewDto>());
public Task<(bool Ok, string? Error)> SetWorktreeStateAsync(string taskId, WorktreeState newState) => Task.FromResult((true, (string?)null));
public Task<ForceRemoveResultDto?> ForceRemoveWorktreeAsync(string taskId) => Task.FromResult<ForceRemoveResultDto?>(null);
public Task<string?> GetWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult<string?>(null); public Task<string?> GetWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult<string?>(null);
public Task<string> GenerateWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(""); public Task<string> GenerateWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult("");
public Task<bool> RunDailyPrepNowAsync() => Task.FromResult(false); public Task<bool> RunDailyPrepNowAsync() => Task.FromResult(false);