feat(external-mcp): let set_list_config write the verify command
SetListConfig previously could only pass VerifyCommand through unchanged; only the UI hub could set it. Add an optional verifyCommand parameter with matching clear/merge/create-vs-delete handling, and split the list result into ListConfigDto so the task-only SetTaskConfig/GetTaskConfig DTOs stay untouched. Also corrects Worker/CLAUDE.md's claim that tasks can override verify_command — it's list-only.
This commit is contained in:
+80
-3
@@ -116,6 +116,85 @@ public sealed class ConfigMcpToolsTests : IDisposable
|
||||
_sut.SetListConfig(listId, clearFields: new[] { "bogus" }, cancellationToken: CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_SetsVerifyCommand()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
|
||||
var result = await _sut.SetListConfig(listId, verifyCommand: "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.Equal("dotnet test", result.Config!.VerifyCommand);
|
||||
var cfg = await _sut.GetListConfig(listId, CancellationToken.None);
|
||||
Assert.Equal("dotnet test", cfg.Config!.VerifyCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_OverwritesVerifyCommand()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
await _sut.SetListConfig(listId, verifyCommand: "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
var result = await _sut.SetListConfig(listId, verifyCommand: "dotnet build", cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.Equal("dotnet build", result.Config!.VerifyCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_ClearVerifyCommand_ClearsOnlyThatField()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
await _sut.SetListConfig(listId, "opus", verifyCommand: "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
var result = await _sut.SetListConfig(listId, clearFields: new[] { "verifyCommand" }, cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.Equal("opus", result.Config!.Model);
|
||||
Assert.Null(result.Config.VerifyCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_ConfigWithOnlyVerifyCommand_IsCreated()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
|
||||
var result = await _sut.SetListConfig(listId, verifyCommand: "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.True(result.Ok);
|
||||
Assert.NotNull(result.Config);
|
||||
Assert.Equal("dotnet test", result.Config!.VerifyCommand);
|
||||
Assert.Null(result.Config.Model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_ClearingEveryOtherField_KeepsConfigWhenVerifyCommandRemains()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
await _sut.SetListConfig(listId, "sonnet", "be terse", "agent.md", 30, "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
var result = await _sut.SetListConfig(
|
||||
listId, clearFields: new[] { "model", "systemPrompt", "agentPath", "maxTurns" }, cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.True(result.Ok);
|
||||
Assert.NotNull(result.Config);
|
||||
Assert.Equal("dotnet test", result.Config!.VerifyCommand);
|
||||
Assert.Null(result.Config.Model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetListConfig_ClearingEveryFieldIncludingVerifyCommand_DeletesConfig()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
await _sut.SetListConfig(listId, "sonnet", verifyCommand: "dotnet test", cancellationToken: CancellationToken.None);
|
||||
|
||||
var result = await _sut.SetListConfig(
|
||||
listId,
|
||||
clearFields: new[] { "model", "systemPrompt", "agentPath", "maxTurns", "verifyCommand" },
|
||||
cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.True(result.Ok);
|
||||
Assert.Null(result.Config);
|
||||
Assert.Null(await _lists.GetConfigAsync(listId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetTaskConfig_PersistsOverrides()
|
||||
{
|
||||
@@ -256,13 +335,12 @@ public sealed class ConfigMcpToolsTests : IDisposable
|
||||
{
|
||||
ListId = listId,
|
||||
Model = "sonnet",
|
||||
VerifyCommand = "dotnet build",
|
||||
SerializeOnFileOverlap = true,
|
||||
});
|
||||
|
||||
var result = await _sut.SetListConfig(
|
||||
listId,
|
||||
clearFields: new[] { "model", "systemPrompt", "agentPath", "maxTurns" },
|
||||
clearFields: new[] { "model", "systemPrompt", "agentPath", "maxTurns", "verifyCommand" },
|
||||
cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.True(result.Ok);
|
||||
@@ -271,7 +349,6 @@ public sealed class ConfigMcpToolsTests : IDisposable
|
||||
var cfg = await _lists.GetConfigAsync(listId);
|
||||
Assert.NotNull(cfg);
|
||||
Assert.Null(cfg!.Model);
|
||||
Assert.Equal("dotnet build", cfg.VerifyCommand);
|
||||
Assert.True(cfg.SerializeOnFileOverlap);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user