diff --git a/CLAUDE.md b/CLAUDE.md index da3a252..e417cd8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,18 +35,23 @@ Two-process system communicating over SignalR (`127.0.0.1:47821`): - EF Core migrations manage schema (Migrations/ folder in ClaudeDo.Data) - `IDbContextFactory` used by singleton consumers (e.g. Worker) - Entity configuration via `IEntityTypeConfiguration` in Configuration/ folder -- Task status flow: Manual | Queued -> Running -> Done | Failed +- Task status flow: Idle | Queued -> Running -> Done | Failed | Cancelled - Worktree state flow: Active -> Merged | Discarded | Kept -- Tags "agent" and "manual" are seeded; "agent" tag marks tasks for automated queue pickup +- The queue picker claims tasks by `Status=Queued` (with `BlockedByTaskId 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 ## Building & Testing +`dotnet build ClaudeDo.slnx` requires .NET 9; on .NET 8 build individual projects instead. + ```bash -dotnet build ClaudeDo.slnx -dotnet test tests/ClaudeDo.Worker.Tests +dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj # pulls in Ui + Data +dotnet build src/ClaudeDo.Worker/ClaudeDo.Worker.csproj +dotnet test tests/ClaudeDo.Worker.Tests # also: Data.Tests, Ui.Tests, Installer.Tests, Releases.Tests ``` ## Docs diff --git a/src/ClaudeDo.App/CLAUDE.md b/src/ClaudeDo.App/CLAUDE.md index a752d3a..07c1c7c 100644 --- a/src/ClaudeDo.App/CLAUDE.md +++ b/src/ClaudeDo.App/CLAUDE.md @@ -19,8 +19,8 @@ Desktop entry point for the ClaudeDo application. Configures DI, initializes the ## DI Registration Pattern -- **Singletons**: SqliteConnectionFactory, all Repositories, WorkerClient, MainWindowViewModel, TaskListViewModel, TaskDetailViewModel, StatusBarViewModel -- **Transients**: TaskEditorViewModel, ListEditorViewModel (created per dialog) +- **Singletons**: `IDbContextFactory`, all Repositories, GitService, WorkerClient, `IReleaseClient`, `InstallerLocator` / `WorkerLocator`, the island VMs (`ListsIslandViewModel`, `TasksIslandViewModel`, `DetailsIslandViewModel`) and `IslandsShellViewModel` (the window's DataContext) +- **Transients**: modal VMs (`SettingsModalViewModel`, `MergeModalViewModel`, `ListSettingsModalViewModel`, `RepoImportModalViewModel`, `WorktreeModalViewModel`, `WorktreesOverviewModalViewModel`, `PrimeClaudeTabViewModel`), several exposed as `Func` factories for on-demand dialog creation ## Notes diff --git a/src/ClaudeDo.Data/CLAUDE.md b/src/ClaudeDo.Data/CLAUDE.md index 6cf100d..b3440eb 100644 --- a/src/ClaudeDo.Data/CLAUDE.md +++ b/src/ClaudeDo.Data/CLAUDE.md @@ -7,18 +7,16 @@ Shared data layer: models, repositories, SQLite infrastructure, and git operatio - **TaskEntity** — Id, ListId, Title, Description, Status (`Idle|Queued|Running|Done|Failed|Cancelled`), PlanningPhase (`None|Active|Finalized` — parent-only), BlockedByTaskId (nullable FK to predecessor in a chain), ScheduledFor, Result, LogPath, timestamps, CommitType, Model / SystemPrompt / AgentPath (nullable overrides), IsStarred, IsMyDay, Notes, ParentTaskId, PlanningSessionId, PlanningSessionToken, PlanningFinalizedAt, CreatedBy. Legacy values `Manual`/`Planning`/`Planned`/`Draft`/`Waiting` were retired; existing rows backfill automatically via the `RetireLegacyTaskStatus` migration. - **ListEntity** — Id, Name, WorkingDir, DefaultCommitType, CreatedAt - **ListConfigEntity** — ListId (PK, 1:1 with list), Model, SystemPrompt, AgentPath (all nullable) -- **TagEntity** — Id (autoincrement), Name (unique) - **WorktreeEntity** — TaskId (PK, 1:1 with task), Path, BranchName, BaseCommit, HeadCommit, DiffStat, State (Active|Merged|Discarded|Kept) - **TaskRunEntity** — per-run record (session_id, tokens, turns, result, structured output, exit code, log path) - **SubtaskEntity**, **AppSettingsEntity**, **AgentInfo** — existing helpers / settings / record for scanned agent files ## Repositories -All repositories use EF Core LINQ queries via `ClaudeDoDbContext`. Exception: `TaskRepository.GetNextQueuedAgentTaskAsync` uses `FromSqlRaw` for atomic queue claim. +All repositories use EF Core LINQ queries via `ClaudeDoDbContext`. The atomic `Queued -> Running` claim lives in the Worker's `QueuePicker` (uses `FromSqlRaw`), not here. -- **TaskRepository** — CRUD, planning helpers (`CreateChildAsync`, `SetPlanningStartedAsync`, `DiscardPlanningAsync`, `TryCompleteParentAsync`, `UpdateChildAsync`), tag management (`GetEffectiveTagsAsync` — union of task + list tags), `UpdateAgentSettingsAsync` (model / system-prompt / agent-path overrides). Status-mutation primitives `MarkRunningAsync` / `MarkDoneAsync` / `MarkFailedAsync` / `FlipAllRunningToFailedAsync` are `internal` and called only by `TaskStateService` in the worker. `CreateChildAsync` produces children with `Status=Idle, PlanningPhase=None`; once their parent's `PlanningPhase` becomes `Finalized`, the chain coordinator queues them. -- **ListRepository** — CRUD, tag junction management, `GetConfigAsync` / `SetConfigAsync` (upsert) / `DeleteConfigAsync` for `list_config` -- **TagRepository** — `GetOrCreateAsync` (idempotent) +- **TaskRepository** — CRUD, planning helpers (`CreateChildAsync`, `SetPlanningStartedAsync`, `DiscardPlanningAsync`, `TryCompleteParentAsync`, `UpdateChildAsync`), `UpdateAgentSettingsAsync` (model / system-prompt / agent-path overrides). Status-mutation primitives `MarkRunningAsync` / `MarkDoneAsync` / `MarkFailedAsync` / `FlipAllRunningToFailedAsync` are `internal` and called only by `TaskStateService` in the worker. `CreateChildAsync` produces children with `Status=Idle, PlanningPhase=None`; once their parent's `PlanningPhase` becomes `Finalized`, the chain coordinator queues them. +- **ListRepository** — CRUD, `GetConfigAsync` / `SetConfigAsync` (upsert) / `DeleteConfigAsync` for `list_config` - **WorktreeRepository** — CRUD, `UpdateHeadAsync`, `SetStateAsync` - **TaskRunRepository**, **SubtaskRepository**, **AppSettingsRepository** @@ -35,7 +33,7 @@ All repositories use EF Core LINQ queries via `ClaudeDoDbContext`. Exception: `T ## Schema -Tables: `lists`, `tasks`, `tags`, `list_tags`, `task_tags`, `worktrees`, `list_config`, `task_runs`, `subtasks`, `app_settings`. Managed by EF Core migrations in the `Migrations/` folder. Seed data: tags "agent" and "manual". The `tasks` table holds `status`, `planning_phase` (default `none`), and `blocked_by_task_id` (FK to `tasks.id`, `ON DELETE SET NULL`). +Tables: `lists`, `tasks`, `worktrees`, `list_config`, `task_runs`, `subtasks`, `app_settings`, `prime_schedules`. Managed by EF Core migrations in the `Migrations/` folder. The `tasks` table holds `status`, `planning_phase` (default `none`), and `blocked_by_task_id` (FK to `tasks.id`, `ON DELETE SET NULL`). ## Conventions diff --git a/src/ClaudeDo.Worker/CLAUDE.md b/src/ClaudeDo.Worker/CLAUDE.md index aa63830..26de170 100644 --- a/src/ClaudeDo.Worker/CLAUDE.md +++ b/src/ClaudeDo.Worker/CLAUDE.md @@ -17,6 +17,8 @@ Worker/ Hub/ — WorkerHub, HubBroadcaster ``` +Interfaces (e.g. `IQueueWaker`, `IPrimeClock`, `ITaskStateService`) live in an `Interfaces/` subfolder within their area; the namespace stays the area namespace. + ## Architecture - **Program.cs** — loads config, inits schema, registers DI, configures SignalR on `/hub`, binds to `127.0.0.1:47821` diff --git a/tests/ClaudeDo.Worker.Tests/CLAUDE.md b/tests/ClaudeDo.Worker.Tests/CLAUDE.md index 9d437f1..1f29911 100644 --- a/tests/ClaudeDo.Worker.Tests/CLAUDE.md +++ b/tests/ClaudeDo.Worker.Tests/CLAUDE.md @@ -20,10 +20,10 @@ xUnit integration tests for the Worker and Data layers. | Area | File | What it covers | |------|------|----------------| | Repositories | `ListRepositoryTests` | CRUD, tag junctions | -| | `TaskRepositoryTests` | CRUD, status transitions, agent tag filtering, effective tags, stale flip | +| | `TaskRepositoryTests` | CRUD, status transitions, stale flip | | Runner | `WorktreeManagerTests` | Worktree creation, commit detection, error on non-git dir | | | `CommitMessageBuilderTests` | Slug generation, title/description truncation | -| | `MessageParserTests` | NDJSON parsing, malformed input | +| | `StreamAnalyzerTests` | NDJSON parsing, session/token/turn extraction | | Services | `QueueServiceTests` | FIFO ordering, override slot contention, cancellation, active tracking | | | `StaleTaskRecoveryTests` | Flips orphaned running tasks to failed |