Merge claudedo/05827da5ecde413e9a2fe8edd45c24a8
This commit is contained in:
@@ -87,6 +87,15 @@ public class PromptFilesTests
|
||||
Assert.DoesNotContain("whenever you are unsure", d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultFor_merge_helper_phase0_treats_brief_as_primary_source()
|
||||
{
|
||||
var d = PromptFiles.DefaultFor(PromptKind.MergeHelper);
|
||||
Assert.Contains("primary source", d, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains("batch_get_tasks", d);
|
||||
Assert.Contains("Do not act on any single task before you have read", d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultFor_merge_helper_initial_has_repo_token()
|
||||
{
|
||||
|
||||
@@ -88,13 +88,13 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
return listId;
|
||||
}
|
||||
|
||||
private async Task SeedTaskAsync(string taskId, string listId, TaskStatus status, string? sessionSkillsJson = null, string title = "T")
|
||||
private async Task SeedTaskAsync(string taskId, string listId, TaskStatus status, string? sessionSkillsJson = null, string title = "T", string? description = null)
|
||||
{
|
||||
using var ctx = _db.CreateContext();
|
||||
await new TaskRepository(ctx).AddAsync(new TaskEntity
|
||||
{
|
||||
Id = taskId, ListId = listId, Title = title, Status = status,
|
||||
CreatedAt = DateTime.UtcNow, SessionSkills = sessionSkillsJson,
|
||||
CreatedAt = DateTime.UtcNow, SessionSkills = sessionSkillsJson, Description = description,
|
||||
});
|
||||
_seededTaskIds.Add(taskId); // a fresh-task ConPTY spec may write a real brief.md under
|
||||
// ~/.todo-app/task-sessions/<taskId> -- clean it up on dispose
|
||||
@@ -562,6 +562,82 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
Assert.Contains(t2, brief);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BuildForMergeHelperAsync_BriefIncludesTaskDescription()
|
||||
{
|
||||
var repo = Path.Combine(_tempDir, "repoDesc");
|
||||
Directory.CreateDirectory(repo);
|
||||
|
||||
var listId = await SeedListAsync(workingDir: repo, name: "Alpha");
|
||||
var t1 = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(t1, listId, TaskStatus.Idle, title: "First task",
|
||||
description: "Do the thing carefully and report back.");
|
||||
|
||||
var svc = BuildService();
|
||||
var spec = await svc.BuildForMergeHelperAsync(new[] { t1 }, listId, CancellationToken.None);
|
||||
var sessionDir = TrackSessionDir(spec);
|
||||
|
||||
var brief = File.ReadAllText(Path.Combine(sessionDir, "brief.md"));
|
||||
Assert.Contains("Do the thing carefully and report back.", brief);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BuildForMergeHelperAsync_TaskWithoutDescription_RendersCleanly()
|
||||
{
|
||||
var repo = Path.Combine(_tempDir, "repoNoDesc");
|
||||
Directory.CreateDirectory(repo);
|
||||
|
||||
var listId = await SeedListAsync(workingDir: repo, name: "Alpha");
|
||||
var t1 = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(t1, listId, TaskStatus.Idle, title: "No description task", description: null);
|
||||
|
||||
var svc = BuildService();
|
||||
var spec = await svc.BuildForMergeHelperAsync(new[] { t1 }, listId, CancellationToken.None);
|
||||
var sessionDir = TrackSessionDir(spec);
|
||||
|
||||
var brief = File.ReadAllText(Path.Combine(sessionDir, "brief.md"));
|
||||
var line = brief.Split('\n').Single(l => l.Contains("No description task"));
|
||||
Assert.Equal($"- [Idle] No description task (id: {t1})", line.TrimEnd('\r'));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BuildForMergeHelperAsync_BriefDescriptionWithCodeFenceAndHeadingsKeepsTaskListRecognizable()
|
||||
{
|
||||
var repo = Path.Combine(_tempDir, "repoMd");
|
||||
Directory.CreateDirectory(repo);
|
||||
|
||||
var listId = await SeedListAsync(workingDir: repo, name: "Alpha");
|
||||
var t1 = Guid.NewGuid().ToString();
|
||||
var t2 = Guid.NewGuid().ToString();
|
||||
var trickyDescription = """
|
||||
# Heading inside description
|
||||
|
||||
- a nested list item
|
||||
- another one
|
||||
|
||||
```csharp
|
||||
var x = "fenced code block";
|
||||
```
|
||||
""";
|
||||
await SeedTaskAsync(t1, listId, TaskStatus.Idle, title: "First task", description: trickyDescription);
|
||||
await SeedTaskAsync(t2, listId, TaskStatus.WaitingForReview, title: "Second task", description: "plain description");
|
||||
|
||||
var svc = BuildService();
|
||||
var spec = await svc.BuildForMergeHelperAsync(new[] { t1, t2 }, listId, CancellationToken.None);
|
||||
var sessionDir = TrackSessionDir(spec);
|
||||
|
||||
var brief = File.ReadAllText(Path.Combine(sessionDir, "brief.md"));
|
||||
var lines = brief.Replace("\r\n", "\n").Split('\n');
|
||||
|
||||
// The two task bullets must still be recognizable top-level list items, unbroken
|
||||
// by the embedded heading/list/code-fence in the first task's description.
|
||||
Assert.Contains(lines, l => l == $"- [Idle] First task (id: {t1})");
|
||||
Assert.Contains(lines, l => l == $"- [WaitingForReview] Second task (id: {t2})");
|
||||
Assert.Contains("Heading inside description", brief);
|
||||
Assert.Contains("fenced code block", brief);
|
||||
Assert.Contains("var x = \"fenced code block\";", brief);
|
||||
}
|
||||
|
||||
// ── CreateMergeHelperTaskAsync ──
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user