fix(worker): close status-force bypasses on Running tasks
update_task_status Idle/Done, WorkerHub.SetTaskStatus, and the UI's Mark Done/Cancelled menu items could all force a Running task's status without going through TaskStateService's guards, leaving its CLI process untracked and its worktree writes silently dropped. Idle now routes through the already-guarded TaskStateService.ResetToIdleAsync instead of the repo's unconditional ResetToManualAsync; Done and SetTaskStatus explicitly reject Running; the context menu disables both entries with a tooltip while running. TaskRunner also now logs a warning whenever a terminal transition (SubmitForChildren/SubmitForReview/Complete/Fail) is rejected instead of silently discarding the run result. DeleteTask's MCP path gets the same friendly foreign-key message WorkerHub.DeleteTask already had for a task with children.
This commit is contained in:
@@ -171,6 +171,13 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
IsRunning ? (true, null) : (false, Loc.T("tasks.reasonNotRunning"));
|
||||
public string? CancelDisabledReason => CancelGate().Reason;
|
||||
|
||||
// Gates "Mark Done"/"Mark Cancelled" in the context menu — forcing either status while the
|
||||
// task is actively running would strand the CLI process untracked (WorkerHub.SetTaskStatus
|
||||
// rejects it server-side too; this is the UI-visible half of that guard).
|
||||
private (bool Can, string? Reason) MarkAsGate() =>
|
||||
IsRunning ? (false, Loc.T("tasks.reasonAlreadyRunning")) : (true, null);
|
||||
public string? MarkAsDisabledReason => MarkAsGate().Reason;
|
||||
|
||||
// "Open quick session" has no precondition today (see A1's file header) — kept as a
|
||||
// placeholder so the menu wiring is uniform; always null until a real gate exists.
|
||||
public string? QuickSessionDisabledReason => null;
|
||||
@@ -318,6 +325,7 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(CancelDisabledReason));
|
||||
OnPropertyChanged(nameof(RefineDisabledReason));
|
||||
OnPropertyChanged(nameof(PlanningDisabledReason));
|
||||
OnPropertyChanged(nameof(MarkAsDisabledReason));
|
||||
}
|
||||
|
||||
partial void OnParentTaskIdChanged(string? value)
|
||||
|
||||
Reference in New Issue
Block a user