diff --git a/src/ClaudeDo.Worker/Planning/PlanningSessionManager.cs b/src/ClaudeDo.Worker/Planning/PlanningSessionManager.cs index 67194ab..c312873 100644 --- a/src/ClaudeDo.Worker/Planning/PlanningSessionManager.cs +++ b/src/ClaudeDo.Worker/Planning/PlanningSessionManager.cs @@ -53,6 +53,19 @@ public sealed class PlanningSessionManager return new PlanningSessionStartContext(taskId, list.WorkingDir, files); } + public async Task DiscardAsync(string taskId, CancellationToken ct) + { + var ok = await _tasks.DiscardPlanningAsync(taskId, ct); + var sessionDir = Path.Combine(_rootDirectory, taskId); + if (Directory.Exists(sessionDir)) + { + try { Directory.Delete(sessionDir, recursive: true); } + catch { /* best effort */ } + } + if (!ok) + throw new InvalidOperationException($"Task {taskId} was not in Planning state; nothing to discard."); + } + public async Task ResumeAsync(string taskId, CancellationToken ct) { var task = await _tasks.GetByIdAsync(taskId, ct) diff --git a/tests/ClaudeDo.Worker.Tests/Planning/PlanningSessionManagerTests.cs b/tests/ClaudeDo.Worker.Tests/Planning/PlanningSessionManagerTests.cs index a587d89..daf1712 100644 --- a/tests/ClaudeDo.Worker.Tests/Planning/PlanningSessionManagerTests.cs +++ b/tests/ClaudeDo.Worker.Tests/Planning/PlanningSessionManagerTests.cs @@ -159,4 +159,20 @@ public sealed class PlanningSessionManagerTests : IDisposable await Assert.ThrowsAsync(() => _sut.ResumeAsync(parent.Id, CancellationToken.None)); } + + [Fact] + public async Task DiscardAsync_DeletesSessionDirAndResetsTask() + { + var (listId, _) = await SeedListAsync(); + var parent = await SeedManualTaskAsync(listId); + var startCtx = await _sut.StartAsync(parent.Id, CancellationToken.None); + Assert.True(Directory.Exists(startCtx.Files.SessionDirectory)); + + await _sut.DiscardAsync(parent.Id, CancellationToken.None); + + Assert.False(Directory.Exists(startCtx.Files.SessionDirectory)); + var loaded = await _tasks.GetByIdAsync(parent.Id); + Assert.Equal(TaskStatus.Manual, loaded!.Status); + Assert.Null(loaded.PlanningSessionToken); + } } \ No newline at end of file