feat(claude-do): Merge-Session soll die Queue selbst beobachten statt fertige
## WO — verifiziert am 2026-09-02, nicht neu suchen - Merge-Phasen-Prompt: `src/ClaudeDo.Data/PromptFiles.cs`, Konstante `MergeHelperMergeDefault` (ab Z. 495). Der neue Warte-Abschnitt gehört zwischen "## Verify once — after the last merge" (Z. 526) und "## Handoff / end" (Z. 542) — also nach dem Verify, vor der Handoff-Entscheidung. - Brief-Template: `MergeHelperInitialDefault` (Z. 555) und `Mer ClaudeDo-Task: 1788adc4-c671-4942-ab78-1ef1812da494
This commit is contained in:
@@ -284,12 +284,12 @@ public sealed class InteractiveLaunchSpecService
|
||||
throw new InvalidOperationException($"list '{list.Name}' has no existing working directory");
|
||||
repoDir = TrimTrailingSeparator(repoDir);
|
||||
|
||||
var briefLines = new List<string>();
|
||||
var briefEntries = new List<(TaskEntity Task, string Line)>();
|
||||
foreach (var id in taskIds)
|
||||
{
|
||||
var task = await taskRepo.GetByIdAsync(id, ct)
|
||||
?? throw new KeyNotFoundException($"Task not found: {id}");
|
||||
briefLines.Add(RenderBriefEntry(task));
|
||||
briefEntries.Add((task, RenderBriefEntry(task)));
|
||||
}
|
||||
|
||||
var sessionDir = Path.Combine(Paths.AppDataRoot(), "merge-helper-sessions", Guid.NewGuid().ToString());
|
||||
@@ -305,7 +305,7 @@ public sealed class InteractiveLaunchSpecService
|
||||
["scope"] = $"List: {list.Name}",
|
||||
["repo"] = repoDir,
|
||||
["handlerTaskId"] = handlerTaskId,
|
||||
["tasks"] = string.Join("\n", briefLines),
|
||||
["tasks"] = RenderGroupedBrief(briefEntries),
|
||||
}), ct);
|
||||
|
||||
var resolvedClaude = WindowsTerminalLauncher.Resolve(_claudePath)
|
||||
@@ -379,12 +379,12 @@ public sealed class InteractiveLaunchSpecService
|
||||
throw new InvalidOperationException($"list '{list.Name}' has no existing working directory");
|
||||
repoDir = TrimTrailingSeparator(repoDir);
|
||||
|
||||
var briefLines = new List<string>();
|
||||
var briefEntries = new List<(TaskEntity Task, string Line)>();
|
||||
foreach (var id in survivingTaskIds)
|
||||
{
|
||||
var task = await taskRepo.GetByIdAsync(id, ct)
|
||||
?? throw new KeyNotFoundException($"Task not found: {id}");
|
||||
briefLines.Add($"- [{task.Status}] {task.Title} (id: {task.Id})");
|
||||
briefEntries.Add((task, $"- [{task.Status}] {task.Title} (id: {task.Id})"));
|
||||
}
|
||||
|
||||
var sessionDir = Path.Combine(Paths.AppDataRoot(), "merge-helper-sessions", Guid.NewGuid().ToString());
|
||||
@@ -408,7 +408,7 @@ public sealed class InteractiveLaunchSpecService
|
||||
["scope"] = $"List: {list.Name}",
|
||||
["repo"] = repoDir,
|
||||
["handlerTaskId"] = taskId,
|
||||
["tasks"] = string.Join("\n", briefLines),
|
||||
["tasks"] = RenderGroupedBrief(briefEntries),
|
||||
["finalNote"] = finalNote,
|
||||
}), ct);
|
||||
|
||||
@@ -444,6 +444,27 @@ public sealed class InteractiveLaunchSpecService
|
||||
// at all. ListRepository normalizes on write now, but rows written before that still carry one.
|
||||
private static string TrimTrailingSeparator(string dir) => Paths.TrimTrailingSeparator(dir)!;
|
||||
|
||||
// A task the picker would still touch (or is mid-run) vs. one that already landed
|
||||
// somewhere terminal-ish. Split the brief on this so a handler session picking up after a
|
||||
// Wait phase can see at a glance which of its tasks are actually ready to review and which
|
||||
// are still moving underneath it -- the flat list this replaces made every task look
|
||||
// equally "done" regardless of status.
|
||||
private static readonly TaskStatus[] StillRunningStatuses =
|
||||
{ TaskStatus.Queued, TaskStatus.Running, TaskStatus.WaitingForChildren };
|
||||
|
||||
private static string RenderGroupedBrief(IReadOnlyList<(TaskEntity Task, string Line)> entries)
|
||||
{
|
||||
var finished = entries.Where(e => !StillRunningStatuses.Contains(e.Task.Status)).Select(e => e.Line).ToList();
|
||||
var running = entries.Where(e => StillRunningStatuses.Contains(e.Task.Status)).Select(e => e.Line).ToList();
|
||||
|
||||
var sections = new List<string>();
|
||||
if (finished.Count > 0)
|
||||
sections.Add("### Done / waiting for review\n" + string.Join("\n", finished));
|
||||
if (running.Count > 0)
|
||||
sections.Add("### Still running\n" + string.Join("\n", running));
|
||||
return string.Join("\n\n", sections);
|
||||
}
|
||||
|
||||
// Renders one task as a brief list item. A description can itself be arbitrary Markdown
|
||||
// (headings, lists, fenced code) — those must not merge into the brief's own task list, so
|
||||
// the description is placed in a fenced code block indented to the list item's continuation
|
||||
|
||||
Reference in New Issue
Block a user