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
@@ -239,7 +239,22 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
// creates one new ClaudeDo task per run to own the session (title/diff/result), deduped by
// TaskId like OpenConPtySessionAsync. The handler still merges the tasks it handles itself
// (no worktree of its own) — see TaskEntity.HandlerBaseCommit/HandlerHeadCommit.
public async System.Threading.Tasks.Task OpenMergeHelperConPtySessionAsync(string listId, IReadOnlyList<string> taskIds)
public System.Threading.Tasks.Task OpenMergeHelperConPtySessionAsync(string listId, IReadOnlyList<string> taskIds)
=> OpenListHandlerConPtySessionAsync(listId, taskIds,
"missionControl.mergeHelperTitle", "missionControl.mergeHelperTaskTitle",
taskId => _worker.GetMergeHelperLaunchSpecAsync(taskIds, listId, taskId));
// Merge-only list-handler session over a list's WaitingForReview tasks (the review list's
// "Let Claude merge the reviews"). Same host-task shape as the full run, but the session
// starts directly at the merge phase via the existing handoff spec — no triage/wait first.
public System.Threading.Tasks.Task OpenMergeReviewConPtySessionAsync(string listId, IReadOnlyList<string> taskIds)
=> OpenListHandlerConPtySessionAsync(listId, taskIds,
"missionControl.mergeReviewsTitle", "missionControl.mergeReviewsTaskTitle",
taskId => _worker.GetMergeHelperHandoffLaunchSpecAsync(taskId, taskIds, "merge"));
private async System.Threading.Tasks.Task OpenListHandlerConPtySessionAsync(
string listId, IReadOnlyList<string> taskIds, string titleKey, string taskTitleKey,
Func<string, System.Threading.Tasks.Task<LaunchSpec>> launchSpec)
{
if (taskIds is not { Count: > 0 }) return;
// The TaskId dedupe below can't help here — CreateMergeHelperTaskAsync mints a brand-new
@@ -249,7 +264,7 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
try
{
var title = Loc.T("missionControl.mergeHelperTitle");
var title = Loc.T(titleKey);
var listName = listId;
try
{
@@ -263,7 +278,7 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
try
{
taskId = await _worker.CreateMergeHelperTaskAsync(taskIds, listId,
Loc.T("missionControl.mergeHelperTaskTitle", listName),
Loc.T(taskTitleKey, listName),
Loc.T("missionControl.mergeHelperTaskDescriptionHeader"));
}
catch (Exception ex)
@@ -279,7 +294,7 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
}
AddConPtyPane(new ConPtyPaneViewModel(taskId, title,
() => DescribeAsync(() => _worker.GetMergeHelperLaunchSpecAsync(taskIds, listId, taskId))));
() => DescribeAsync(() => launchSpec(taskId))));
}
finally
{