4.9 KiB
4.9 KiB
ClaudeDo
A desktop task management app that executes tasks autonomously via Claude CLI in isolated git worktrees.
Architecture
Two-process system communicating over SignalR (127.0.0.1:47821):
- ClaudeDo.App — Avalonia desktop entry point, DI container setup
- ClaudeDo.Ui — Views, ViewModels, SignalR client (MVVM with CommunityToolkit.Mvvm)
- ClaudeDo.Data — SQLite data layer, repositories, models, GitService
- ClaudeDo.Worker — ASP.NET Core hosted service, task queue, Claude CLI runner
- ClaudeDo.Worker.Tests — xUnit integration tests with real SQLite and real git
Tech Stack
- .NET 8.0, Avalonia 12.0.0 (Fluent theme)
- SQLite (WAL mode) via Entity Framework Core (Microsoft.EntityFrameworkCore.Sqlite)
- SignalR for real-time IPC
- CommunityToolkit.Mvvm (
[ObservableProperty],[RelayCommand]) - Git worktrees for task isolation
Key Paths
- DB:
~/.todo-app/todo.db - UI config:
~/.todo-app/ui.config.json - Worker config:
~/.todo-app/worker.config.json - Logs:
~/.todo-app/logs/ - Worktrees: configured per worker (sibling or central strategy)
Conventions
- Repository pattern — each entity has its own async repository
- All data operations are async with CancellationToken support
- EF Core migrations manage schema (Migrations/ folder in ClaudeDo.Data)
IDbContextFactory<ClaudeDoDbContext>used by singleton consumers (e.g. Worker)- Entity configuration via
IEntityTypeConfiguration<T>in Configuration/ folder - Task status flow: Idle | Queued -> Running -> WaitingForReview -> Done | Failed | Cancelled. A standalone task's successful run lands in WaitingForReview (planning children go straight to Done); from review you can approve (merges the worktree into the target branch, then Done; conflicts keep it in WaitingForReview), reject-rerun (Queued, resumes the session with feedback), reject-park (Idle), or cancel (Cancelled). Tasks with no active worktree (sandbox run / improvement parent) are approved straight to Done.
- Worktree state flow: Active -> Merged | Discarded | Kept
- The queue picker claims tasks by
Status=Queued(withBlockedByTaskId IS NULL); the legacy tag system was removed - Interfaces live in an
Interfaces/subfolder beside their consumers (namespace unchanged) - Small single-consumer helper types live in their consumer's file, not standalone files
- Commit messages use conventional format:
{commitType}(slug): title - Views use compiled bindings (
x:DataType) - ViewModels use
[ObservableProperty]and[RelayCommand]source generators
Working style (autonomous)
For any non-trivial feature, bug, or change, run this loop without hand-holding:
- Brainstorm first (superpowers:brainstorming) — ask clarifying questions one at a time, propose 2–3 options with a recommendation, present a short design, get approval before building.
- Write it down — a spec in
docs/superpowers/specs/YYYY-MM-DD-<topic>-design.mdand a step-by-step plan indocs/superpowers/plans/(superpowers:writing-plans). Commit the docs. - Implement on main with superpowers:subagent-driven-development — one subagent per task, TDD, build + test, commit per task with Conventional Commits. Once the plan is approved, do NOT pause for re-approval between tasks; only stop for genuine decisions or blockers.
- Trust but verify — read each subagent's diff and run the build/tests yourself before marking a task done.
- Bugs → superpowers:systematic-debugging (find the root cause before any fix).
- Never claim UI works without running it — explicitly flag visual-verification gaps for the user to check.
Commit freely (per task + the spec/plan docs). Never push without asking.
Building & Testing
dotnet build ClaudeDo.slnx requires .NET 9; on .NET 8 build individual projects with -c Release (a running Worker locks the Debug output).
dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release # pulls in Ui + Data
dotnet build src/ClaudeDo.Worker/ClaudeDo.Worker.csproj -c Release
dotnet test tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj -c Release # also: Data.Tests, Ui.Tests, Localization.Tests, Installer.Tests, Releases.Tests
Gotchas
- Subagents: use the
sonnetmodel; stage files explicitly by path — nevergit add -A(parallel sessions often leave unrelated WIP in the tree). - Icons:
PathIconfills its geometry. Line-art/stroke icons must be authored as filled geometry, or rendered with a strokedPath— otherwise they render invisible. - Localization:
locales/en.jsonandlocales/de.jsonkeys must stay in parity (Localization.Tests enforces it). - Test fakes: changing
IWorkerClient/WorkerHub/ ViewModel constructors breaks hand-rolled fakes in both test projects — update them.
Docs
docs/plan.md— full architecture and design specdocs/open.md— verification checklist and improvement backlogdocs/improvement-plan.md— prioritized improvement items