fix(worker): carry ExpectsNoDiff into the relocated merge MCP tools
Conflict resolution for the #266 merge: #247 had moved PreviewMerge/PreviewMergeSet and MergePreviewSetEntryDto out of ExternalMcpService into MergeMcpTools, so #266's in-place edits to those had to be re-applied at the new location, together with the PreviewMergeSet_ReportsExpectsNoDiffPerTask test.
This commit is contained in:
+12
-8
@@ -57,7 +57,11 @@ public sealed record MergePreviewToolDto(
|
|||||||
public sealed record MergePreviewSetEntryDto(
|
public sealed record MergePreviewSetEntryDto(
|
||||||
string TaskId, string Status, IReadOnlyList<string> ConflictFiles, int ChangedFileCount, int Behind, string? Error, bool IsEmpty = false,
|
string TaskId, string Status, IReadOnlyList<string> ConflictFiles, int ChangedFileCount, int Behind, string? Error, bool IsEmpty = false,
|
||||||
int? VerifyExitCode = null, long? VerifyDurationMs = null, string? VerifyOutputTail = null,
|
int? VerifyExitCode = null, long? VerifyDurationMs = null, string? VerifyOutputTail = null,
|
||||||
IReadOnlyList<string>? StaleFiles = null, int? Number = null);
|
IReadOnlyList<string>? StaleFiles = null, int? Number = null,
|
||||||
|
// Mirrors TaskEntity.ExpectsNoDiff -- lets the merge helper tell a deliberately empty diff
|
||||||
|
// (verification/audit/research task) apart from a task that silently failed to commit, both
|
||||||
|
// of which otherwise show IsEmpty=true with no other distinguishing signal.
|
||||||
|
bool ExpectsNoDiff = false);
|
||||||
|
|
||||||
public sealed record FileOverlapDto(string File, IReadOnlyList<string> TaskIds, IReadOnlyList<int> Numbers);
|
public sealed record FileOverlapDto(string File, IReadOnlyList<string> TaskIds, IReadOnlyList<int> Numbers);
|
||||||
|
|
||||||
@@ -461,7 +465,7 @@ public sealed class MergeMcpTools
|
|||||||
IProgress<ProgressNotificationValue>? progress = null)
|
IProgress<ProgressNotificationValue>? progress = null)
|
||||||
{
|
{
|
||||||
taskId = await TaskIdResolver.ResolveAsync(_tasks, taskId, cancellationToken);
|
taskId = await TaskIdResolver.ResolveAsync(_tasks, taskId, cancellationToken);
|
||||||
var (preview, behind, _, isEmpty, staleFiles, _) = await PreviewMergeCoreAsync(taskId, targetBranch, runVerify: true, cancellationToken, progress);
|
var (preview, behind, _, isEmpty, staleFiles, _, _) = await PreviewMergeCoreAsync(taskId, targetBranch, runVerify: true, cancellationToken, progress);
|
||||||
return new MergePreviewToolDto(preview.Status, preview.ConflictFiles, preview.ChangedFileCount, behind, isEmpty,
|
return new MergePreviewToolDto(preview.Status, preview.ConflictFiles, preview.ChangedFileCount, behind, isEmpty,
|
||||||
preview.VerifyExitCode, preview.VerifyDurationMs, preview.VerifyOutputTail, staleFiles);
|
preview.VerifyExitCode, preview.VerifyDurationMs, preview.VerifyOutputTail, staleFiles);
|
||||||
}
|
}
|
||||||
@@ -503,10 +507,10 @@ public sealed class MergeMcpTools
|
|||||||
var taskId = taskIds[i];
|
var taskId = taskIds[i];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (preview, behind, changedFiles, isEmpty, staleFiles, number) = await PreviewMergeCoreAsync(taskId, targetBranch, runVerify, cancellationToken, progress);
|
var (preview, behind, changedFiles, isEmpty, staleFiles, number, expectsNoDiff) = await PreviewMergeCoreAsync(taskId, targetBranch, runVerify, cancellationToken, progress);
|
||||||
entries.Add(new MergePreviewSetEntryDto(
|
entries.Add(new MergePreviewSetEntryDto(
|
||||||
taskId, preview.Status, preview.ConflictFiles, preview.ChangedFileCount, behind, null, isEmpty,
|
taskId, preview.Status, preview.ConflictFiles, preview.ChangedFileCount, behind, null, isEmpty,
|
||||||
preview.VerifyExitCode, preview.VerifyDurationMs, preview.VerifyOutputTail, staleFiles, number));
|
preview.VerifyExitCode, preview.VerifyDurationMs, preview.VerifyOutputTail, staleFiles, number, expectsNoDiff));
|
||||||
filesByTask[taskId] = changedFiles;
|
filesByTask[taskId] = changedFiles;
|
||||||
numbersByTask[taskId] = number;
|
numbersByTask[taskId] = number;
|
||||||
}
|
}
|
||||||
@@ -515,7 +519,7 @@ public sealed class MergeMcpTools
|
|||||||
var task = await _tasks.GetByIdAsync(taskId, cancellationToken);
|
var task = await _tasks.GetByIdAsync(taskId, cancellationToken);
|
||||||
entries.Add(new MergePreviewSetEntryDto(
|
entries.Add(new MergePreviewSetEntryDto(
|
||||||
taskId, TaskMergeService.PreviewUnavailable, Array.Empty<string>(), 0, 0, ex.Message,
|
taskId, TaskMergeService.PreviewUnavailable, Array.Empty<string>(), 0, 0, ex.Message,
|
||||||
Number: task?.Number));
|
Number: task?.Number, ExpectsNoDiff: task?.ExpectsNoDiff ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressReporter.ReportItem(progress, "Previewing merges", i + 1, taskIds.Count);
|
ProgressReporter.ReportItem(progress, "Previewing merges", i + 1, taskIds.Count);
|
||||||
@@ -573,7 +577,7 @@ public sealed class MergeMcpTools
|
|||||||
// (its commits already sit on the list's working dir) — falls back to the fixed
|
// (its commits already sit on the list's working dir) — falls back to the fixed
|
||||||
// HandlerBaseCommit..HandlerHeadCommit range, reporting a synthetic "clean" preview of that
|
// HandlerBaseCommit..HandlerHeadCommit range, reporting a synthetic "clean" preview of that
|
||||||
// range's own diff-stat instead of throwing "has no worktree".
|
// range's own diff-stat instead of throwing "has no worktree".
|
||||||
private async Task<(MergePreviewResult Preview, int Behind, IReadOnlyList<string> ChangedFiles, bool IsEmpty, IReadOnlyList<string> StaleFiles, int Number)> PreviewMergeCoreAsync(
|
private async Task<(MergePreviewResult Preview, int Behind, IReadOnlyList<string> ChangedFiles, bool IsEmpty, IReadOnlyList<string> StaleFiles, int Number, bool ExpectsNoDiff)> PreviewMergeCoreAsync(
|
||||||
string taskId, string? targetBranch, bool runVerify, CancellationToken ct,
|
string taskId, string? targetBranch, bool runVerify, CancellationToken ct,
|
||||||
IProgress<ProgressNotificationValue>? progress = null)
|
IProgress<ProgressNotificationValue>? progress = null)
|
||||||
{
|
{
|
||||||
@@ -615,7 +619,7 @@ public sealed class MergeMcpTools
|
|||||||
.Intersect(targetChangedSinceFork, StringComparer.OrdinalIgnoreCase)
|
.Intersect(targetChangedSinceFork, StringComparer.OrdinalIgnoreCase)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return (preview, behind, changedFiles, changedFiles.Count == 0, staleFiles, task.Number);
|
return (preview, behind, changedFiles, changedFiles.Count == 0, staleFiles, task.Number, task.ExpectsNoDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.HandlerBaseCommit is { Length: > 0 } handlerBase && task.HandlerHeadCommit is { Length: > 0 } handlerHead)
|
if (task.HandlerBaseCommit is { Length: > 0 } handlerBase && task.HandlerHeadCommit is { Length: > 0 } handlerHead)
|
||||||
@@ -632,7 +636,7 @@ public sealed class MergeMcpTools
|
|||||||
// No fork point to diff against: a handler task commits straight onto the list's
|
// No fork point to diff against: a handler task commits straight onto the list's
|
||||||
// working dir instead of a branch, so there is nothing else that could have "changed
|
// working dir instead of a branch, so there is nothing else that could have "changed
|
||||||
// in the target since the fork".
|
// in the target since the fork".
|
||||||
return (preview, 0, changedFiles, isEmpty, Array.Empty<string>(), task.Number);
|
return (preview, 0, changedFiles, isEmpty, Array.Empty<string>(), task.Number, task.ExpectsNoDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidOperationException($"Task {taskId} has no worktree.");
|
throw new InvalidOperationException($"Task {taskId} has no worktree.");
|
||||||
|
|||||||
@@ -1139,6 +1139,22 @@ public sealed class MergeMcpToolsTests : IDisposable
|
|||||||
Assert.Empty(result.Overlaps);
|
Assert.Empty(result.Overlaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PreviewMergeSet_ReportsExpectsNoDiffPerTask()
|
||||||
|
{
|
||||||
|
if (!GitAvailable) { Assert.True(true, "git not available -- skipping"); return; }
|
||||||
|
|
||||||
|
var (task, list, _) = await SeedWorktreeAsync(TaskStatus.WaitingForReview);
|
||||||
|
task.ExpectsNoDiff = true;
|
||||||
|
await _tasks.UpdateAsync(task, CancellationToken.None);
|
||||||
|
var target = await new GitService().GetCurrentBranchAsync(list.WorkingDir!, CancellationToken.None);
|
||||||
|
var sut = BuildSut(CreateQueue());
|
||||||
|
|
||||||
|
var result = await sut.PreviewMergeSet([task.Id], target, cancellationToken: CancellationToken.None);
|
||||||
|
|
||||||
|
Assert.True(Assert.Single(result.Tasks).ExpectsNoDiff);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PreviewMergeSet_ReportsProgressPerTask()
|
public async Task PreviewMergeSet_ReportsProgressPerTask()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user