feat: ship agent-first mission control v0.2.57
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s

This commit is contained in:
AzuTear
2026-07-31 22:39:47 +02:00
parent 3bc7622977
commit f5552218bc
535 changed files with 95242 additions and 8791 deletions
+15 -34
View File
@@ -98,15 +98,17 @@ public sealed class McpToolsTests
"nexus_create_child_task",
"nexus_create_task",
"nexus_get_activity",
"nexus_get_agent_proposal",
"nexus_get_board",
"nexus_get_children",
"nexus_get_task",
"nexus_handoff",
"nexus_propose_agent",
"nexus_update_status"
}.OrderBy(n => n).ToList();
Assert.Equal(expected, toolMethods);
Assert.Equal(10, toolMethods.Count);
Assert.Equal(12, toolMethods.Count);
}
[Fact]
@@ -415,7 +417,7 @@ public sealed class McpToolsTests
public async Task ResolveCaller_RejectsUnknownAgentId()
{
await using var fixture = await McpToolsFixture.CreateAsync();
fixture.SetCallerAgent("hacker");
fixture.SetCallerAgentWithoutAuthentication("hacker");
await Assert.ThrowsAsync<UnauthorizedAccessException>(
() => fixture.Tools.CreateTask("Should fail"));
@@ -468,16 +470,14 @@ internal sealed class McpToolsFixture : IAsyncDisposable
var db = new NexusDbContext(options);
await db.Database.EnsureCreatedAsync();
var configPath = CreateAgentConfigFile();
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AgentConfigPath"] = configPath,
["NexusApiKey"] = "test-service-key"
})
.Build();
var agentService = new AgentService(configuration, new FakeRuntime());
var agentService = new AgentService(new StubOpenClawControlService());
var liveUpdateService = new LiveUpdateService();
var activityRepository = new ActivityRepository(db, liveUpdateService);
var taskRepository = new TaskRepository(db);
@@ -522,6 +522,16 @@ internal sealed class McpToolsFixture : IAsyncDisposable
}
public void SetCallerAgent(string agentId)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Headers["X-Agent-Id"] = agentId;
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(
[new Claim(ClaimTypes.Role, "Service")],
"ApiKey"));
HttpContextAccessor.HttpContext = httpContext;
}
public void SetCallerAgentWithoutAuthentication(string agentId)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Headers["X-Agent-Id"] = agentId;
@@ -550,33 +560,4 @@ internal sealed class McpToolsFixture : IAsyncDisposable
HttpContextAccessor.HttpContext = httpContext;
}
private static string CreateAgentConfigFile()
{
var path = Path.Combine(Path.GetTempPath(), $"agent-config-{Guid.NewGuid():N}.json");
File.WriteAllText(path,
"""
{
"agents": {
"defaults": {
"workspace": "/workspace/default",
"model": {
"primary": "deepseek/deepseek-v4-flash"
}
},
"list": [
{ "id": "iris", "name": "iris", "model": { "primary": "openai/gpt-5.5" } },
{ "id": "product-owner", "name": "product-owner" },
{ "id": "programmer", "name": "programmer" },
{ "id": "programmer-fast", "name": "programmer-fast" },
{ "id": "reviewer", "name": "reviewer" },
{ "id": "architekt", "name": "architekt" },
{ "id": "executor", "name": "executor" },
{ "id": "researcher", "name": "researcher" }
]
}
}
""");
return path;
}
}