Merge claudedo/113934cda24a4ae99e15d77fca29507e

This commit is contained in:
mika kuns
2026-07-29 13:25:08 +02:00
3 changed files with 35 additions and 2 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ Interfaces (e.g. `IQueueWaker`, `IPrimeClock`, `ITaskStateService`) live in an `
- `RunHistoryMcpTools``ListRuns`, `GetRun`, `GetTaskLog` (latest run's log, tail-capped at 256 KB) - `RunHistoryMcpTools``ListRuns`, `GetRun`, `GetTaskLog` (latest run's log, tail-capped at 256 KB)
- `AgentMcpTools``ListAgents` - `AgentMcpTools``ListAgents`
- `LifecycleMcpTools``ResetFailedTask` - `LifecycleMcpTools``ResetFailedTask`
- `AppSettingsMcpTools``GetAppSettings` (read-only) - `AppSettingsMcpTools``GetAppSettings` (read-only; includes `MaxParallelExecutions`)
- `AttachmentMcpTools``AddTaskAttachment(taskId, fileName, textContent?|base64Content?)`, `ListTaskAttachments`, `RemoveTaskAttachment`. Re-attaching the same fileName overwrites; add/remove refuse on a Running task. - `AttachmentMcpTools``AddTaskAttachment(taskId, fileName, textContent?|base64Content?)`, `ListTaskAttachments`, `RemoveTaskAttachment`. Re-attaching the same fileName overwrites; add/remove refuse on a Running task.
- `ExternalMcpService` also exposes two daily-prep tools: - `ExternalMcpService` also exposes two daily-prep tools:
- `GetDailyPrepCandidates` — returns Idle, non-blocked tasks in a git repo NOT excluded by `AppSettings.ReportExcludedPaths` and not already `IsMyDay`, plus the current Idle MyDay tasks and `maxTasks` (= `DailyPrepMaxTasks`). Repo-exclusion logic lives in the `DailyPrepFilter` helper (same file). - `GetDailyPrepCandidates` — returns Idle, non-blocked tasks in a git repo NOT excluded by `AppSettings.ReportExcludedPaths` and not already `IsMyDay`, plus the current Idle MyDay tasks and `maxTasks` (= `DailyPrepMaxTasks`). Repo-exclusion logic lives in the `DailyPrepFilter` helper (same file).
+3 -1
View File
@@ -8,6 +8,7 @@ namespace ClaudeDo.Worker.External;
public sealed record AppSettingsReadDto( public sealed record AppSettingsReadDto(
string DefaultModel, int DefaultMaxTurns, string DefaultPermissionMode, string DefaultModel, int DefaultMaxTurns, string DefaultPermissionMode,
int MaxParallelExecutions,
string WorktreeStrategy, string? CentralWorktreeRoot, string WorktreeStrategy, string? CentralWorktreeRoot,
bool WorktreeAutoCleanupEnabled, int WorktreeAutoCleanupDays); bool WorktreeAutoCleanupEnabled, int WorktreeAutoCleanupDays);
@@ -18,13 +19,14 @@ public sealed class AppSettingsMcpTools
public AppSettingsMcpTools(IDbContextFactory<ClaudeDoDbContext> dbFactory) => _dbFactory = dbFactory; public AppSettingsMcpTools(IDbContextFactory<ClaudeDoDbContext> dbFactory) => _dbFactory = dbFactory;
[McpServerTool, Description("Read the worker's app-level defaults (model, max turns, permission mode, worktree strategy). Read-only.")] [McpServerTool, Description("Read the worker's app-level defaults (model, max turns, permission mode, max parallel execution slots, worktree strategy). Read-only.")]
public async Task<AppSettingsReadDto> GetAppSettings(CancellationToken cancellationToken) public async Task<AppSettingsReadDto> GetAppSettings(CancellationToken cancellationToken)
{ {
using var ctx = await _dbFactory.CreateDbContextAsync(cancellationToken); using var ctx = await _dbFactory.CreateDbContextAsync(cancellationToken);
var row = await new AppSettingsRepository(ctx).GetAsync(cancellationToken); var row = await new AppSettingsRepository(ctx).GetAsync(cancellationToken);
return new AppSettingsReadDto( return new AppSettingsReadDto(
row.DefaultModel, row.DefaultMaxTurns, row.DefaultPermissionMode, row.DefaultModel, row.DefaultMaxTurns, row.DefaultPermissionMode,
row.MaxParallelExecutions,
row.WorktreeStrategy, row.CentralWorktreeRoot, row.WorktreeStrategy, row.CentralWorktreeRoot,
row.WorktreeAutoCleanupEnabled, row.WorktreeAutoCleanupDays); row.WorktreeAutoCleanupEnabled, row.WorktreeAutoCleanupDays);
} }
@@ -0,0 +1,31 @@
using ClaudeDo.Data.Models;
using ClaudeDo.Worker.External;
using ClaudeDo.Worker.Tests.Infrastructure;
using Microsoft.EntityFrameworkCore;
namespace ClaudeDo.Worker.Tests.External;
public sealed class AppSettingsMcpToolsTests : IDisposable
{
private readonly DbFixture _db = new();
public void Dispose() => _db.Dispose();
[Fact]
public async Task GetAppSettings_ReturnsMaxParallelExecutionsFromDb()
{
using (var ctx = _db.CreateContext())
{
var row = await ctx.AppSettings.FirstOrDefaultAsync(s => s.Id == AppSettingsEntity.SingletonId)
?? throw new InvalidOperationException("Expected seeded app_settings row.");
row.MaxParallelExecutions = 3;
await ctx.SaveChangesAsync();
}
var sut = new AppSettingsMcpTools(_db.CreateFactory());
var result = await sut.GetAppSettings(CancellationToken.None);
Assert.Equal(3, result.MaxParallelExecutions);
}
}