using System.ComponentModel; using ClaudeDo.Data.Models; using ClaudeDo.Data.Repositories; using ClaudeDo.Ui.Services; using TaskStatus = ClaudeDo.Data.Models.TaskStatus; namespace ClaudeDo.Ui.Tests; /// /// No-op base for tests. Override only the members a /// test actually exercises; everything else returns a benign default. Keeping the /// full interface surface here means new interface members only break this file. /// public abstract class StubWorkerClient : IWorkerClient { #pragma warning disable CS0067 // interface-mandated events; tests don't raise them public event PropertyChangedEventHandler? PropertyChanged; public event Action? TaskStartedEvent; public event Action? TaskFinishedEvent; public event Action? TaskUpdatedEvent; public event Action? ConnectionRestoredEvent; public event Action? WorktreeUpdatedEvent; public event Action? ListUpdatedEvent; public event Action? TaskMessageEvent; public event Action? WorkerLogReceivedEvent; public event Action? TaskQuestionAskedEvent; public event Action? TaskQuestionResolvedEvent; public event Action? InteractiveSessionStartedEvent; public event Action? InteractiveSessionEndedEvent; public event Action>? InteractiveQueueChangedEvent; public event Action? InteractiveMessageSentEvent; public event Action? PrepStartedEvent; public event Action? PrepLineEvent; public event Action? PrepFinishedEvent; public event Action? RefineStartedEvent; public event Action? RefineFinishedEvent; public event Action? PlanningMergeStartedEvent; public event Action? PlanningSubtaskMergedEvent; 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; } public int RunDailyPrepNowCalls { get; private set; } public virtual IReadOnlyList GetActiveTasks() => System.Array.Empty(); public void RaiseTaskStarted(string slot, string taskId, DateTime startedAt) => TaskStartedEvent?.Invoke(slot, taskId, startedAt); public void RaiseTaskFinished(string slot, string taskId, string status, DateTime finishedAt) => TaskFinishedEvent?.Invoke(slot, taskId, status, finishedAt); public void RaiseTaskMessage(string taskId, string line) => TaskMessageEvent?.Invoke(taskId, line); public void RaiseTaskUpdated(string taskId) => TaskUpdatedEvent?.Invoke(taskId); public void RaiseConnectionRestored() => ConnectionRestoredEvent?.Invoke(); public void RaiseTaskQuestionAsked(string taskId, string questionId, string question) => TaskQuestionAskedEvent?.Invoke(taskId, questionId, question); public void RaiseTaskQuestionResolved(string taskId, string questionId) => TaskQuestionResolvedEvent?.Invoke(taskId, questionId); public void RaisePrepStarted() => PrepStartedEvent?.Invoke(); public void RaisePrepLine(string line) => PrepLineEvent?.Invoke(line); public void RaisePrepFinished(bool ok) => PrepFinishedEvent?.Invoke(ok); public void RaiseInteractiveStarted(string taskId) => InteractiveSessionStartedEvent?.Invoke(taskId); public void RaiseInteractiveEnded(string taskId) => InteractiveSessionEndedEvent?.Invoke(taskId); public void RaiseInteractiveQueueChanged(string taskId, IReadOnlyList pending) => InteractiveQueueChangedEvent?.Invoke(taskId, pending); public void RaiseInteractiveMessageSent(string taskId, string text) => InteractiveMessageSentEvent?.Invoke(taskId, text); 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; public virtual Task ContinueTaskAsync(string taskId, string followUpPrompt) => Task.CompletedTask; public (string TaskId, string QuestionId, string Answer)? LastAnswer { get; private set; } public virtual Task AnswerTaskQuestionAsync(string taskId, string questionId, string answer) { LastAnswer = (taskId, questionId, answer); return Task.CompletedTask; } public PendingQuestionDto? PendingQuestion; public virtual Task GetPendingQuestionAsync(string taskId) => Task.FromResult(PendingQuestion); 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; public virtual Task ApproveReviewAsync(string taskId, string targetBranch) => Task.FromResult(null); public virtual Task PreviewMergeAsync(string taskId, string targetBranch) => Task.FromResult(null); public virtual Task MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage) => Task.FromResult(new MergeResultDto("merged", System.Array.Empty(), null)); public virtual Task RejectReviewToQueueAsync(string taskId, string feedback) => Task.CompletedTask; public virtual Task RejectReviewToIdleAsync(string taskId) => Task.CompletedTask; public virtual Task CancelReviewAsync(string taskId) => Task.CompletedTask; public virtual Task StartConflictMergeAsync(string taskId, string targetBranch) => Task.FromResult(new MergeResultDto("conflict", System.Array.Empty(), null)); public virtual Task GetMergeConflictDocumentsAsync(string taskId) => Task.FromResult(new MergeConflictDocumentsDto(taskId, System.Array.Empty())); public virtual Task WriteConflictResolutionAsync(string taskId, string path, string resolvedContent) => Task.CompletedTask; public virtual Task ContinueConflictMergeAsync(string taskId) => Task.FromResult(new MergeResultDto("merged", System.Array.Empty(), null)); public virtual Task AbortConflictMergeAsync(string taskId) => Task.CompletedTask; public virtual Task StartPlanningSessionAsync(string taskId, CancellationToken ct = default) => Task.CompletedTask; public virtual Task OpenInteractiveTerminalAsync(string taskId, CancellationToken ct = default) => Task.CompletedTask; public virtual Task ResumePlanningSessionAsync(string taskId, CancellationToken ct = default) => Task.CompletedTask; public virtual Task DiscardPlanningSessionAsync(string taskId, bool dequeueQueuedChildren = false, CancellationToken ct = default) => Task.FromResult(new DiscardPlanningOutcome(DiscardPlanningResult.Discarded, 0, 0)); public virtual Task FinalizePlanningSessionAsync(string taskId, bool queueAgentTasks = true, CancellationToken ct = default) => Task.CompletedTask; public virtual Task GetPendingDraftCountAsync(string taskId, CancellationToken ct = default) => Task.FromResult(0); public virtual Task GetMergeTargetsAsync(string taskId) => Task.FromResult(null); public virtual Task> GetRecentLogsAsync() => Task.FromResult>(Array.Empty()); public virtual Task> GetPlanningAggregateAsync(string planningTaskId) => Task.FromResult>(Array.Empty()); public virtual Task BuildPlanningIntegrationBranchAsync(string planningTaskId, string targetBranch) => Task.FromResult(null); public virtual Task ContinuePlanningMergeAsync(string planningTaskId) => Task.CompletedTask; public virtual Task AbortPlanningMergeAsync(string planningTaskId) => Task.CompletedTask; public virtual Task QueuePlanningSubtasksAsync(string parentTaskId, CancellationToken ct = default) => Task.CompletedTask; public virtual Task GetWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(null); public virtual Task GenerateWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(""); 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; public virtual Task DeleteDailyNoteAsync(string id) => Task.CompletedTask; public string LastPrepLog = ""; public virtual Task GetLastPrepLogAsync() => Task.FromResult(LastPrepLog); public virtual Task RefineTaskAsync(string taskId) => Task.CompletedTask; public virtual Task GetOnlineInboxStateAsync() => Task.FromResult(null); public virtual Task SetOnlineInboxConfigAsync(OnlineInboxConfigInputDto input) => Task.CompletedTask; public virtual Task SetOnlineInboxAuthAsync(string refreshToken) => Task.CompletedTask; public virtual Task ClearOnlineInboxAuthAsync() => Task.CompletedTask; public List<(string TaskId, string Text)> SentInteractive { get; } = new(); public virtual Task SendInteractiveMessageAsync(string taskId, string text) { SentInteractive.Add((taskId, text)); return Task.CompletedTask; } public List StoppedInteractive { get; } = new(); public virtual Task StopInteractiveSessionAsync(string taskId) { StoppedInteractive.Add(taskId); return Task.CompletedTask; } public List InterruptedInteractive { get; } = new(); public virtual Task InterruptInteractiveSessionAsync(string taskId) { InterruptedInteractive.Add(taskId); return Task.CompletedTask; } protected void RaisePropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }