8823265e5afa38250a150ec3fb449bcc0cef9a14
Slice 2 of the worker state consolidation refactor (spec sections 2 and 8). Adds Worker/State/ITaskStateService + TaskStateService as the single component that mutates Status, PlanningPhase, and BlockedByTaskId. Each transition is one atomic ExecuteUpdate with a WHERE filter on the expected source status, so parallel claims are TOCTOU-free. Side effects (queue wake on -> Queued, hub TaskUpdated broadcast, chain advance + parent completion on terminal child) are owned by the service so callers no longer need to remember them. Migrated callers (mechanical, behavior preserved): - TaskRunner: HandleSuccess/HandleFailure/MarkFailed/RunAsync/ContinueAsync - StaleTaskRecovery: bulk recover stale Running tasks - TaskResetService: status flip (worktree cleanup stays in service) - PlanningSessionManager.StartAsync: status flip via state, token write via repo - PlanningChainCoordinator.OnChildFinishedAsync: routes the next-sibling write through state.UnblockAsync (Slice 4 finishes the rewrite) - ExternalMcpService.UpdateTaskStatus: Queued case via state.EnqueueAsync Repo Mark*Async helpers (MarkRunning/MarkDone/MarkFailed/FlipAllRunningToFailed) are now internal; ClaudeDo.Data grants InternalsVisibleTo to ClaudeDo.Worker and ClaudeDo.Worker.Tests for the existing repo-level tests. DI: TaskStateService is registered as Singleton in both the main app and the external-MCP app; the queue-wake delegate captures sp -> QueueService.WakeQueue to break the TaskStateService -> QueueService -> TaskRunner -> TaskStateService construction cycle. PlanningChainCoordinator takes Func<ITaskStateService> for the same reason; Slice 3 will replace both with IQueueWaker. Tests: TaskStateServiceTests covers happy + reject for every transition, the parallel StartRunningAsync claim race, child-terminal chain advancement, and stale recovery. Existing service/repo tests are updated to construct the new state-service via a TaskStateServiceBuilder helper. Pre-existing constructor drift in QueueService/ExternalMcp/PlanningHub tests is patched to keep the test project building (the surrounding test logic is otherwise untouched). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ClaudeDo
A desktop task management app that executes tasks autonomously via Claude CLI in isolated git worktrees.
Queue up coding tasks, and ClaudeDo picks them up one by one — each running in its own worktree so your main branch stays clean.
Architecture
Two-process system communicating over SignalR:
| Project | Role |
|---|---|
| ClaudeDo.App | Avalonia desktop entry point, DI container setup |
| ClaudeDo.Ui | Views, ViewModels, SignalR client (MVVM) |
| ClaudeDo.Data | SQLite data layer, repositories, models, GitService |
| ClaudeDo.Worker | ASP.NET Core hosted service, task queue, Claude CLI runner |
┌────────────────┐ SignalR ┌────────────────┐
│ ClaudeDo.App │◄───────────►│ ClaudeDo.Worker │
│ (Avalonia) │ 127.0.0.1 │ (ASP.NET Core) │
│ │ :47821 │ │
│ ┌────────────┐│ │ ┌────────────┐ │
│ │ Ui ││ │ │ TaskQueue │ │
│ │(ViewModels)││ │ │ Claude CLI │ │
│ └────────────┘│ │ └────────────┘ │
└───────┬────────┘ └───────┬────────┘
│ │
└──────────────┬───────────────┘
│
┌───────┴───────┐
│ ClaudeDo.Data │
│ (SQLite) │
└───────────────┘
Tech Stack
- .NET 8.0
- Avalonia 12.0.0 (Fluent theme)
- SQLite (WAL mode) via Entity Framework Core (EF Core + Migrations)
- SignalR for real-time IPC between UI and Worker
- CommunityToolkit.Mvvm for source-generated MVVM
- Git worktrees for task isolation
Prerequisites
- .NET 8.0 SDK
- Claude CLI installed and authenticated
- Git
Getting Started
# Build
dotnet build src/ClaudeDo.App
dotnet build src/ClaudeDo.Worker
# Run tests
dotnet test tests/ClaudeDo.Worker.Tests
# Run the app
dotnet run --project src/ClaudeDo.App
How It Works
- Create a task in the UI and tag it with "agent" to mark it for automated execution.
- The Worker picks up queued tasks and runs each one via Claude CLI in an isolated git worktree.
- When done, the worktree can be merged, kept for review, or discarded.
Task status flow: Manual | Queued → Running → Done | Failed
Worktree state flow: Active → Merged | Discarded | Kept
Configuration
All data and config lives under ~/.todo-app/:
| File | Purpose |
|---|---|
todo.db |
SQLite database |
ui.config.json |
UI settings |
worker.config.json |
Worker settings (worktree strategy, etc.) |
logs/ |
Application logs |
Project Structure
ClaudeDo.slnx
├── src/
│ ├── ClaudeDo.App/ # Desktop entry point
│ ├── ClaudeDo.Ui/ # Views & ViewModels
│ ├── ClaudeDo.Data/ # Data access layer
│ └── ClaudeDo.Worker/ # Background task runner
├── tests/
│ └── ClaudeDo.Worker.Tests/
├── schema/
│ └── schema.sql # Database schema
└── docs/
├── plan.md # Architecture & design spec
├── open.md # Verification checklist & backlog
└── improvement-plan.md # Prioritized improvements
License
Private — not licensed for redistribution.
Description