feat(ui): confirm before closing a running ConPTY session

The tile's own X killed a live Claude session with no confirmation, unlike
the semantically similar Abandon-run action. Gate the close behind the same
ConfirmAsync mechanism, but only when Terminal.IsRunning -- a dead session
(StartError or exited-after-startup) still closes immediately since the X
there is pure cleanup.
This commit is contained in:
mika kuns
2026-09-10 13:52:36 +02:00
parent 395874d834
commit eb62371430
4 changed files with 76 additions and 3 deletions
@@ -449,7 +449,7 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
private void AddConPtyPane(ConPtyPaneViewModel pane)
{
pane.ErrorReported += OnConPtyPaneError;
pane.CloseRequested += CloseConPtySession;
pane.CloseRequested += OnPaneCloseRequested;
pane.SubmitForReviewRequested += OnPaneSubmitForReview;
pane.SessionDiedAfterStartup += OnPaneSessionDied;
pane.AbandonRunRequested += OnPaneAbandonRun;
@@ -543,11 +543,27 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
}
}
// The tile's own X: a reflex click must not silently kill a live session the way it would a
// regular window. Confirm only when the terminal is actually running -- a dead one (StartError,
// or HasExited i.e. the #290 exited banner) is pure cleanup and closes straight away, same as it
// always did. Every other close path (handoff replacing a pane, submit-for-review, abandon-run)
// still calls CloseConPtySession directly and is unaffected.
private async void OnPaneCloseRequested(ConPtyPaneViewModel pane)
{
if (pane.Terminal.IsRunning)
{
if (ConfirmAsync is null) return;
if (!await ConfirmAsync(Loc.T("missionControl.closeSessionConfirm"))) return;
}
CloseConPtySession(pane);
}
private void CloseConPtySession(ConPtyPaneViewModel pane)
{
if (!ConPtySessions.Contains(pane)) return;
pane.ErrorReported -= OnConPtyPaneError;
pane.CloseRequested -= CloseConPtySession;
pane.CloseRequested -= OnPaneCloseRequested;
pane.SubmitForReviewRequested -= OnPaneSubmitForReview;
pane.SessionDiedAfterStartup -= OnPaneSessionDied;
pane.AbandonRunRequested -= OnPaneAbandonRun;
@@ -601,7 +617,7 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
foreach (var c in ConPtySessions.ToList())
{
c.ErrorReported -= OnConPtyPaneError;
c.CloseRequested -= CloseConPtySession;
c.CloseRequested -= OnPaneCloseRequested;
c.SubmitForReviewRequested -= OnPaneSubmitForReview;
c.SessionDiedAfterStartup -= OnPaneSessionDied;
c.AbandonRunRequested -= OnPaneAbandonRun;