Merge branch 'claudedo/9f963a215bb34ca4a28050d4f39178d3'
This commit is contained in:
@@ -75,7 +75,10 @@ public interface IWorkerClient : INotifyPropertyChanged
|
||||
Task<List<string>> InstallSessionSkillAsync(string url);
|
||||
Task UpdateSessionSkillAsync(string sourceUrl);
|
||||
Task RemoveSessionSkillAsync(string sourceUrl);
|
||||
Task SetTaskStatusAsync(string taskId, TaskStatus status);
|
||||
/// <summary>Returns the base-dirty heads-up when this transition just queued the task against
|
||||
/// a list whose working dir has uncommitted changes (null otherwise) — a new worktree forks
|
||||
/// from the last commit, not the working tree, so those changes won't be included.</summary>
|
||||
Task<BaseDirtyWarningDto?> SetTaskStatusAsync(string taskId, TaskStatus status);
|
||||
Task<MergeResultDto?> ApproveReviewAsync(string taskId, string targetBranch);
|
||||
Task<MergePreviewDto?> PreviewMergeAsync(string taskId, string targetBranch);
|
||||
Task<MergeResultDto> MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage);
|
||||
|
||||
@@ -483,9 +483,10 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
||||
public Task RemoveSessionSkillAsync(string sourceUrl)
|
||||
=> _hub.InvokeAsync("RemoveSessionSkill", sourceUrl);
|
||||
|
||||
public async Task SetTaskStatusAsync(string taskId, ClaudeDo.Data.Models.TaskStatus status)
|
||||
public async Task<BaseDirtyWarningDto?> SetTaskStatusAsync(string taskId, ClaudeDo.Data.Models.TaskStatus status)
|
||||
{
|
||||
await _hub.InvokeAsync("SetTaskStatus", taskId, status.ToString());
|
||||
var result = await _hub.InvokeAsync<SetTaskStatusResultDto>("SetTaskStatus", taskId, status.ToString());
|
||||
return result?.BaseDirty;
|
||||
}
|
||||
|
||||
public async Task<MergeResultDto?> ApproveReviewAsync(string taskId, string targetBranch)
|
||||
@@ -690,6 +691,8 @@ public sealed record SessionSkillDto(
|
||||
public sealed record WorktreeCleanupDto(int Removed);
|
||||
public sealed record WorktreeResetDto(int Removed, int TasksAffected, bool Blocked, int RunningTasks);
|
||||
public record MergeResultDto(string Status, IReadOnlyList<string> ConflictFiles, string? ErrorMessage);
|
||||
public record BaseDirtyWarningDto(int ModifiedCount, int UntrackedCount);
|
||||
public record SetTaskStatusResultDto(BaseDirtyWarningDto? BaseDirty);
|
||||
public record MergePreviewDto(string Status, IReadOnlyList<string> ConflictFiles, int ChangedFileCount);
|
||||
public record MergeTargetsDto(string DefaultBranch, IReadOnlyList<string> LocalBranches);
|
||||
public record MergeConflictDocumentsDto(string TaskId, IReadOnlyList<ConflictDocumentDto> Files);
|
||||
|
||||
@@ -1097,12 +1097,20 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
if (Task == null) return;
|
||||
try
|
||||
{
|
||||
await _worker.SetTaskStatusAsync(Task.Id, ClaudeDo.Data.Models.TaskStatus.Queued);
|
||||
var baseDirty = await _worker.SetTaskStatusAsync(Task.Id, ClaudeDo.Data.Models.TaskStatus.Queued);
|
||||
AgentState = "queued";
|
||||
ReportBaseDirty(baseDirty);
|
||||
}
|
||||
catch { /* offline */ }
|
||||
}
|
||||
|
||||
private void ReportBaseDirty(BaseDirtyWarningDto? warning)
|
||||
{
|
||||
if (warning is null) return;
|
||||
ErrorReported?.Invoke(Loc.T(
|
||||
"vm.queue.baseDirtyWarning", warning.ModifiedCount, warning.UntrackedCount));
|
||||
}
|
||||
|
||||
private bool CanEnqueue() =>
|
||||
Task != null && _worker.IsConnected && IsIdle
|
||||
&& (!Task.IsChild || Task.ParentFinalized);
|
||||
@@ -1168,8 +1176,9 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
|
||||
try
|
||||
{
|
||||
await _worker.SetTaskStatusAsync(Task.Id, ClaudeDo.Data.Models.TaskStatus.Queued);
|
||||
var baseDirty = await _worker.SetTaskStatusAsync(Task.Id, ClaudeDo.Data.Models.TaskStatus.Queued);
|
||||
AgentState = "queued";
|
||||
ReportBaseDirty(baseDirty);
|
||||
}
|
||||
catch { /* offline */ }
|
||||
}
|
||||
|
||||
@@ -887,10 +887,21 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
public async Task SetStatusOnRowAsync(TaskRowViewModel row, TaskStatus status)
|
||||
{
|
||||
if (_worker is null) return;
|
||||
try { await _worker.SetTaskStatusAsync(row.Id, status); }
|
||||
try
|
||||
{
|
||||
var baseDirty = await _worker.SetTaskStatusAsync(row.Id, status);
|
||||
ReportBaseDirty(baseDirty);
|
||||
}
|
||||
catch { /* offline; broadcast won't fire */ }
|
||||
}
|
||||
|
||||
private void ReportBaseDirty(BaseDirtyWarningDto? warning)
|
||||
{
|
||||
if (warning is null) return;
|
||||
ErrorReported?.Invoke(Loc.T(
|
||||
"vm.queue.baseDirtyWarning", warning.ModifiedCount, warning.UntrackedCount));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SendToQueueAsync(TaskRowViewModel? row)
|
||||
{
|
||||
@@ -917,7 +928,11 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
// Goes through the worker hub (TaskStateService.EnqueueAsync) rather than a raw EF write
|
||||
// so the manual/draft-child guards apply here too; the row refreshes from the resulting
|
||||
// TaskUpdated broadcast.
|
||||
try { await _worker.SetTaskStatusAsync(row.Id, TaskStatus.Queued); }
|
||||
try
|
||||
{
|
||||
var baseDirty = await _worker.SetTaskStatusAsync(row.Id, TaskStatus.Queued);
|
||||
ReportBaseDirty(baseDirty);
|
||||
}
|
||||
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.tasksIsland.sendToQueueFailed", ex.Message)); }
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,13 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
|
||||
{
|
||||
if (string.IsNullOrEmpty(taskId)) return;
|
||||
if (ConPtySessions.Any(s => s.TaskId == taskId)) return;
|
||||
try { await _worker.SetTaskStatusAsync(taskId, ClaudeDo.Data.Models.TaskStatus.Queued); }
|
||||
try
|
||||
{
|
||||
var baseDirty = await _worker.SetTaskStatusAsync(taskId, ClaudeDo.Data.Models.TaskStatus.Queued);
|
||||
if (baseDirty is not null)
|
||||
ErrorReported?.Invoke(Loc.T(
|
||||
"vm.queue.baseDirtyWarning", baseDirty.ModifiedCount, baseDirty.UntrackedCount));
|
||||
}
|
||||
catch { /* best-effort enqueue */ }
|
||||
await RefreshQueueAsync();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user