feat(mission-control): Handler-Run per Knopf abbrechen
Ein "Abandon run"-Knopf an Handler-Panes fragt HandlerRoundState.Get(handlerTaskId) nach den noch offenen (Queued/Running) Tasks des Laufs, bestaetigt mit Anzahl, cancelt jeden ueber den bestehenden CancelTaskAsync-Pfad und schliesst danach die Session -- ein Schritt statt Tile schliessen + Queue separat abbrechen. Ohne offene Tasks (oder ohne Round-Eintrag) schliesst die Aktion direkt, ohne Dialog. Nur an den beiden Handler-Panes sichtbar (IsListHandler), normale Task-/Ad-hoc- Panes bleiben unveraendert.
This commit is contained in:
@@ -73,6 +73,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
private readonly TicketClientFactory _ticketClients;
|
||||
private readonly TicketImportService _ticketImport;
|
||||
private readonly HandlerRestartCoordinator? _handlerRestart;
|
||||
private readonly HandlerRoundState? _roundState;
|
||||
|
||||
public WorkerHub(
|
||||
QueueService queue,
|
||||
@@ -112,7 +113,8 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
TicketPatStore ticketPat = null!,
|
||||
TicketClientFactory ticketClients = null!,
|
||||
TicketImportService ticketImport = null!,
|
||||
HandlerRestartCoordinator? handlerRestart = null)
|
||||
HandlerRestartCoordinator? handlerRestart = null,
|
||||
HandlerRoundState? roundState = null)
|
||||
{
|
||||
_queue = queue;
|
||||
_waker = waker;
|
||||
@@ -152,6 +154,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
_ticketClients = ticketClients;
|
||||
_ticketImport = ticketImport;
|
||||
_handlerRestart = handlerRestart;
|
||||
_roundState = roundState;
|
||||
}
|
||||
|
||||
// Persistence boundary for the session_skills JSON-array columns (task/list/global).
|
||||
@@ -810,6 +813,24 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
_ = _handlerRestart.OnSessionExitedAsync(taskId, exitCode, CancellationToken.None);
|
||||
}
|
||||
|
||||
// The Mission Control "abandon run" action: what a handler round queued/started that is still
|
||||
// open (Queued or Running), read from the structured HandlerRoundState store rather than
|
||||
// parsed out of the handler task's description. Empty when there is no round entry (7-day
|
||||
// retention, or a run from before this feature) or the round has no open tasks -- the caller
|
||||
// treats both as "nothing to confirm, just close the pane".
|
||||
public async Task<IReadOnlyList<HandlerOpenTaskDto>> GetHandlerOpenTasks(string handlerTaskId)
|
||||
{
|
||||
var round = _roundState?.Get(handlerTaskId);
|
||||
if (round is not { TaskIds.Count: > 0 }) return Array.Empty<HandlerOpenTaskDto>();
|
||||
|
||||
await using var ctx = await _dbFactory.CreateDbContextAsync();
|
||||
return await ctx.Tasks.AsNoTracking()
|
||||
.Where(t => round.TaskIds.Contains(t.Id)
|
||||
&& (t.Status == TaskStatus.Queued || t.Status == TaskStatus.Running))
|
||||
.Select(t => new HandlerOpenTaskDto(t.Id, t.Title))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
// Starts a planning session (worktree + prompt files + token, task -> Planning) and returns
|
||||
// the launch spec for an embedded ConPTY planning terminal -- the ConPTY replacement for
|
||||
// StartPlanningSessionAsync's external wt window. On any spec-build failure the just-started
|
||||
|
||||
Reference in New Issue
Block a user