feat(ui): Review-Merge-Button — Claude nimmt Waiting-for-Review pro Liste ab

Neuer Button in der virtuellen Review-Liste: öffnet das Merge-Helper-Auswahlmodal
im Review-Modus (alle WaitingForReview-Tasks repo-verknüpfter Listen, gruppiert
unter Listen-Headern, alle vorgetickt) und startet pro gewählter Liste eine
ConPTY-Handler-Session direkt in der Merge-Phase — via bestehendem Handoff-Spec
(nextPhase "merge"), kein Triage/Wait davor. Handler-Host-Task wie beim vollen
"Let Claude handle it"-Lauf (HandlerBaseCommit, IsManual).
This commit is contained in:
mika kuns
2026-08-27 08:44:33 +02:00
parent d0c726baa0
commit 741c7ac58d
11 changed files with 293 additions and 8 deletions
@@ -124,6 +124,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
[NotifyPropertyChangedFor(nameof(IsTasksEmptyRepoHintVisible))]
private bool _isLetClaudeVisible;
[ObservableProperty] private bool _isQuickClaudeVisible;
[ObservableProperty] private bool _isMergeReviewsVisible;
/// <summary>No visible tasks below the add-task row — every item lands in one of
/// Overdue/Open/Completed, so all-false here always means the list has zero items.</summary>
@@ -147,6 +148,13 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
[RelayCommand]
private void LetClaudeHandle() => LetClaudeHandleRequested?.Invoke(this, EventArgs.Empty);
// "Let Claude merge the reviews" on the virtual review list — the shell routes it to the
// review-scoped selection modal, which starts one merge-phase handler session per list.
public event EventHandler? MergeReviewsRequested;
[RelayCommand]
private void MergeReviews() => MergeReviewsRequested?.Invoke(this, EventArgs.Empty);
// Opens a task-less ConPTY session directly in the current list's working dir. The shell owns
// Mission Control, so this just raises an event for it to act on (mirrors OpenConPtySessionRequested).
public event Action<string>? OpenQuickClaudeSessionRequested;
@@ -411,7 +419,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
ShowOpenLabel = false;
ShowNotesRow = false;
if (listChanged) SelectFrom(null, "list-change");
if (list is null) { IsLetClaudeVisible = false; IsQuickClaudeVisible = false; LoadTask = Task.CompletedTask; return; }
if (list is null) { IsLetClaudeVisible = false; IsQuickClaudeVisible = false; IsMergeReviewsVisible = false; LoadTask = Task.CompletedTask; return; }
HeaderTitle = list.Name;
HeaderEyebrow = DateTime.Now.ToString("dddd · MMM dd", CultureInfo.InvariantCulture).ToUpperInvariant();
@@ -419,6 +427,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
IsMyDayList = list.Id == "smart:my-day";
IsLetClaudeVisible = list.Kind == ListKind.User && !string.IsNullOrWhiteSpace(list.WorkingDir);
IsQuickClaudeVisible = IsLetClaudeVisible;
IsMergeReviewsVisible = list.Id == "virtual:review";
LoadTask = LoadForListAsync(list, ct, reusable);
}