Queuing (update_task_status, batch_update_task_status) and run_task_now now surface a non-blocking baseDirty warning (separate modified/untracked counts) when the list's working dir has uncommitted changes at enqueue time, since a new worktree forks from the commit tip and silently misses them. BaseDirtyChecker caches per working dir for a few seconds so a batch queue over many tasks in one list only shells out to git once. The UI surfaces the same warning via the footer error strip on queue actions.
62 lines
2.1 KiB
C#
62 lines
2.1 KiB
C#
using ClaudeDo.Data;
|
|
using ClaudeDo.Worker.Git;
|
|
using ClaudeDo.Worker.Hub;
|
|
using ClaudeDo.Worker.Planning;
|
|
using ClaudeDo.Worker.Queue;
|
|
using ClaudeDo.Worker.State;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
|
namespace ClaudeDo.Worker.Tests.Infrastructure;
|
|
|
|
/// Test-only helper that wires TaskStateService and PlanningChainCoordinator
|
|
/// against a shared DB factory, breaking the Func cycle between them.
|
|
public static class TaskStateServiceBuilder
|
|
{
|
|
public sealed record Built(
|
|
TaskStateService State,
|
|
PlanningChainCoordinator Chain,
|
|
CapturingHubContext Hub,
|
|
Func<int> WakeCount,
|
|
CountingQueueWaker Waker,
|
|
RunCancellationRegistry RunCancels);
|
|
|
|
public static Built Build(
|
|
IDbContextFactory<ClaudeDoDbContext> dbFactory,
|
|
Func<IActiveMergeState>? mergeState = null,
|
|
IBaseDirtyChecker? baseDirtyChecker = null)
|
|
{
|
|
var hub = new CapturingHubContext();
|
|
var broadcaster = new HubBroadcaster(hub);
|
|
var waker = new CountingQueueWaker();
|
|
var runCancels = new RunCancellationRegistry(NullLogger<RunCancellationRegistry>.Instance);
|
|
|
|
TaskStateService? state = null;
|
|
var chain = new PlanningChainCoordinator(dbFactory, () => state!);
|
|
state = new TaskStateService(
|
|
dbFactory,
|
|
broadcaster,
|
|
waker,
|
|
chain,
|
|
runCancels,
|
|
mergeState ?? (() => NoActiveMergeState.Instance),
|
|
baseDirtyChecker ?? new BaseDirtyChecker(new ClaudeDo.Data.Git.GitService(), NullLogger<BaseDirtyChecker>.Instance),
|
|
NullLogger<TaskStateService>.Instance);
|
|
|
|
return new Built(state, chain, hub, () => waker.Count, waker, runCancels);
|
|
}
|
|
}
|
|
|
|
file sealed class NoActiveMergeState : IActiveMergeState
|
|
{
|
|
public static readonly NoActiveMergeState Instance = new();
|
|
public bool HasActiveMerge(string taskId) => false;
|
|
}
|
|
|
|
public sealed class CountingQueueWaker : IQueueWaker
|
|
{
|
|
private int _count;
|
|
public int Count => Volatile.Read(ref _count);
|
|
public void Wake() => Interlocked.Increment(ref _count);
|
|
}
|