feat(mission-control): give the list handler its own review task
"Let Claude handle it" now creates one ClaudeDo task per run to host the ConPTY session (Idle/IsManual, never queued) instead of an untracked ad-hoc tile, so the run has a real title, diff, and review outcome. Since the handler merges its own changes straight into the list's working dir, the task never gets a WorktreeEntity; its review range lives as new HandlerBaseCommit/HandlerHeadCommit columns on TaskEntity instead, reusing the existing commit-range diff machinery and keeping it out of the worktrees overview entirely.
This commit is contained in:
@@ -70,6 +70,7 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
private InteractiveLaunchSpecService BuildService() =>
|
||||
new(_db.CreateFactory(), _seeder, _registry,
|
||||
new WorktreeManager(new GitService(), _db.CreateFactory(), new WorkerConfig(), NullLogger<WorktreeManager>.Instance),
|
||||
new GitService(),
|
||||
new WorkerConfig { ClaudeBin = _claudeStubPath });
|
||||
|
||||
private async Task<string> SeedListAsync(string? workingDir = null, string name = "L")
|
||||
@@ -477,6 +478,65 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
Assert.Contains(t2, brief);
|
||||
}
|
||||
|
||||
// ── CreateMergeHelperTaskAsync ──
|
||||
|
||||
[Fact]
|
||||
public async Task CreateMergeHelperTaskAsync_EmptyTaskIds_ThrowsInvalidOperation()
|
||||
{
|
||||
var listId = await SeedListAsync(workingDir: _tempDir);
|
||||
var svc = BuildService();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => svc.CreateMergeHelperTaskAsync(Array.Empty<string>(), listId, "title", "header", CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateMergeHelperTaskAsync_UnknownList_ThrowsKeyNotFound()
|
||||
{
|
||||
var taskId = Guid.NewGuid().ToString();
|
||||
var svc = BuildService();
|
||||
await Assert.ThrowsAsync<KeyNotFoundException>(
|
||||
() => svc.CreateMergeHelperTaskAsync(new[] { taskId }, "no-such-list", "title", "header", CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateMergeHelperTaskAsync_ListWithoutExistingWorkingDir_ThrowsInvalidOperation()
|
||||
{
|
||||
var listId = await SeedListAsync(workingDir: Path.Combine(_tempDir, "gone"));
|
||||
var taskId = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(taskId, listId, TaskStatus.WaitingForReview);
|
||||
|
||||
var svc = BuildService();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => svc.CreateMergeHelperTaskAsync(new[] { taskId }, listId, "title", "header", CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateMergeHelperTaskAsync_CreatesIdleManualTask_StampsHandlerBaseCommit()
|
||||
{
|
||||
if (!GitAvailable) { Assert.True(true, "git not available -- skipping"); return; }
|
||||
|
||||
var repo = CreateRepo();
|
||||
var listId = await SeedListAsync(workingDir: repo.RepoDir, name: "Alpha");
|
||||
var t1 = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(t1, listId, TaskStatus.WaitingForReview, title: "First task");
|
||||
|
||||
var svc = BuildService();
|
||||
var newTaskId = await svc.CreateMergeHelperTaskAsync(
|
||||
new[] { t1 }, listId, "List handler: Alpha", "Tasks handled by this run:", CancellationToken.None);
|
||||
|
||||
using var readCtx = _db.CreateContext();
|
||||
var created = await new TaskRepository(readCtx).GetByIdAsync(newTaskId);
|
||||
Assert.NotNull(created);
|
||||
Assert.Equal("List handler: Alpha", created!.Title);
|
||||
Assert.Equal(TaskStatus.Idle, created.Status);
|
||||
Assert.True(created.IsManual);
|
||||
Assert.Equal(repo.BaseCommit, created.HandlerBaseCommit);
|
||||
Assert.Null(created.HandlerHeadCommit);
|
||||
Assert.Contains("Tasks handled by this run:", created.Description);
|
||||
Assert.Contains("First task", created.Description);
|
||||
Assert.Contains(t1, created.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPlanningStart_MapsPlanningArgsAndEnv()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user