fix(ui): gate queueing on an open interactive ConPTY session
A task-based ConPTY session leaves the row Idle in the DB (sessions never touch status), so nothing stopped the queue picker from claiming it too: CanSendToQueue ignored HasInteractiveSession, and both TasksIslandViewModel. SendToQueueAsync and MissionControlViewModel.EnqueueTaskAsync (drag-to-queue) wrote Status=Queued straight via EF, bypassing TaskStateService entirely and its manual/draft-child guards. That let an autonomous claude process spawn in the same worktree a user was hand-editing in the ConPTY pane. Add !HasInteractiveSession to CanSendToQueue, and route both UI enqueue paths through IWorkerClient.SetTaskStatusAsync (worker hub -> TaskStateService. EnqueueAsync) instead of raw EF writes. The interactive-session gate itself stays in the UI: the worker has no notion of a UI-hosted ConPTY pane.
This commit is contained in:
@@ -99,11 +99,15 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
public bool CanRemoveFromQueue => IsQueued || HasQueuedSubtasks;
|
||||
// "Send to queue" is the single queue entry. On a finalized planning parent it queues the
|
||||
// plan (children) via CanQueuePlan; an Active (not-yet-finalized) planning parent is hidden —
|
||||
// it must be finalized first.
|
||||
// it must be finalized first. The worker never sees a UI-hosted ConPTY session (it never
|
||||
// touches task status), so this gate has to live here: queueing a task the user is actively
|
||||
// hand-editing in an interactive pane would spawn an autonomous run racing it in the same
|
||||
// worktree.
|
||||
public bool CanSendToQueue => !IsRunning && !IsQueued && !IsWaitingForReview && !HasQueuedSubtasks
|
||||
&& (!IsChild || ParentFinalized)
|
||||
&& PlanningPhase != PlanningPhase.Active
|
||||
&& !IsManual;
|
||||
&& !IsManual
|
||||
&& !HasInteractiveSession;
|
||||
// Parent-level "send plan to queue" — only once the plan is finalized (children Planned).
|
||||
// Drives the routing inside SendToQueue, not a separate menu entry.
|
||||
public bool CanQueuePlan => !IsChild && HasPlanningChildren
|
||||
@@ -242,6 +246,7 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(StatusLabel));
|
||||
OnPropertyChanged(nameof(ShowStatusChip));
|
||||
OnPropertyChanged(nameof(InteractiveChipTooltip));
|
||||
OnPropertyChanged(nameof(CanSendToQueue));
|
||||
}
|
||||
|
||||
partial void OnHasQueuedSubtasksChanged(bool value)
|
||||
|
||||
Reference in New Issue
Block a user