# ClaudeDo.Ui

Avalonia UI layer: views, viewmodels, converters, and the SignalR client.

## Pattern

MVVM with CommunityToolkit.Mvvm source generators:
- `[ObservableProperty]` for bindable properties
- `[RelayCommand]` for commands (supports async and CanExecute)
- All ViewModels inherit `ViewModelBase` (extends `ObservableObject`)

## Views

- **MainWindow** — 3-column DockPanel layout (lists | tasks | detail) with GridSplitter, status bar at bottom
- **TaskListView** — ListBox of tasks with add/edit/delete toolbar
- **TaskDetailView** — Task info, live log output, worktree section (merge/keep/discard)
- **TaskEditorView** — Modal dialog for task create/edit
- **ListEditorView** — Modal dialog for list create/edit
- **StatusBarView** — Connection status indicator, active task display
- **ListSettingsModalView** — edits list name, working dir, default commit type, and per-list Model/SystemPrompt/AgentPath/MaxTurns, each showing the inherited (global) value with a source-aware "inherited · Global / override" badge and a reset-to-inherited button; also deletes the list (and its tasks) via a confirmed "Delete list" button. Opened via context menu or gear button on a list row.
- **RepoImportModalView** — bulk-creates lists from git repos discovered under chosen parent folders. Opened via the folder button beside "New list" in the Lists island, or the "Add repos as lists…" Help-menu item. Repos already wired to a list show as disabled/"(already added)".
- **DetailsIslandView** — contains an "Agent settings (overrides)" expander with per-task Model/MaxTurns/AgentPath (override semantics, each showing the resolved inherited value as a placeholder plus a source-aware "inherited · List / inherited · Global / override" badge and reset button via the reusable `InheritedBadge` control + `InheritanceResolver`) and a SystemPrompt text box (additive — shows the inherited prompt as a "prepended automatically" note). Disabled while task is running. When notes mode is active (`IsNotesMode`), it hosts **NotesEditorView** instead of the task detail. When prep mode is active (`IsPrepMode`), it hosts the daily-prep panel (Plan day button, empty-state hint, embedded **SessionTerminalView**). The task header, metadata footer (delete/close), and **AgentStripView** are gated on `IsTaskDetailVisible` — they are hidden in both notes and prep mode.
- **WeeklyReportModalView** — opened from Help menu ("Wochenbericht…"); date-range pickers default to "since last standup weekday → today"; Generate/Regenerate button; renders markdown via MarkdownView; reports are cached per range.
- **NotesEditorView** — day navigator (prev/next/date-picker/Today), bullet add/edit/delete for daily notes.
- **SessionTerminalView** — reusable log terminal; exposes StyledProperties `Entries`, `Label`, `IsRunning`, `IsDone`, `IsFailed`. Used for both the task `Log` and the prep `PrepLog`.
- **SettingsModalView** — Prime Claude tab contains a `DailyPrepMaxTasks` numeric editor.
- **TasksIslandView** (MyDay header) — icon buttons visible only when `IsMyDayList`: broom icon = `ClearDayCommand`, stroked-sun icon ("Plan My Day") = `ShowPrepLogCommand`.

All views use compiled bindings (`x:DataType`).

## ViewModels

- **MainWindowViewModel** — root coordinator; manages list collection, selected list, dialog creation via `Func<T>` factories
- **TaskListViewModel** — manages task collection for selected list; handles CRUD, "Run Now"
- **TaskDetailViewModel** — displays task details, streams live log, controls worktree operations
- **TaskItemViewModel** / **ListItemViewModel** — lightweight display VMs
- **TaskEditorViewModel** / **ListEditorViewModel** — dialog VMs with validation
- **StatusBarViewModel** — connection state and active tasks
- **WeeklyReportModalViewModel** — drives the weekly report modal
- **NotesEditorViewModel** — manages daily note bullet CRUD for the selected day
- **DetailsIslandViewModel** gains `IsNotesMode`, `ShowNotes()`, and hosts `NotesEditorViewModel`. Also gains daily-prep mode: `IsPrepMode`, `PrepLog` (`ObservableCollection<LogLineViewModel>`), `ShowPrep()`, `PlanDayCommand` (calls `RunDailyPrepNowAsync`), `ShowPrepEmptyState`, and computed `IsTaskDetailVisible` (= `!IsNotesMode && !IsPrepMode`). Subscribes to `PrepStartedEvent`, `PrepLineEvent`, `PrepFinishedEvent`; streams lines into `PrepLog` via `StreamLineFormatter` (same path as task logs). On open, if log is empty and no run is in progress, loads persisted last run via `GetLastPrepLogAsync`. The WorkConsole Session tab gains a mergeability indicator (`MergePreviewPresenter`) and a single-task Merge button; indicator is populated via `PreviewMergeAsync` and displayed for tasks in WaitingForReview.
- **TasksIslandViewModel** gains a pinned "Notes" pseudo-row (`ShowNotesRow`, `OpenNotesCommand`, `NotesRequested` event) that switches the Details island to notes mode. Also gains `IsMyDayList` (true when selected list is `smart:my-day`), `ShowPrepLogCommand` (raises `PrepRequested` event → shell calls `Details.ShowPrep()`), and `ClearDayCommand` (calls `ClearMyDayAsync`).

## Services

- **WorkerClient** / **IWorkerClient** — SignalR client connecting to `http://127.0.0.1:47821/hub`. Auto-reconnect with exponential backoff. Methods: StartAsync, RunNowAsync, CancelTaskAsync, WakeQueueAsync, ContinueTaskAsync, ResetTaskAsync, GetAgentsAsync, UpdateAppSettingsAsync, UpdateListAsync, UpdateListConfigAsync, GetListConfigAsync, UpdateTaskAgentSettingsAsync, `ApproveReviewAsync(taskId, targetBranch) -> MergeResultDto`, `PreviewMergeAsync(taskId, targetBranch) -> MergePreviewDto`, `MergeTaskAsync`, `GetWeekReportAsync`, `GenerateWeekReportAsync`, `GetDailyNotesAsync`, `AddDailyNoteAsync`, `UpdateDailyNoteAsync`, `DeleteDailyNoteAsync`, `RunDailyPrepNowAsync`, `ClearMyDayAsync`, `GetLastPrepLogAsync`. Events: TaskStarted, TaskFinished, TaskMessage, TaskUpdated, WorktreeUpdated, ListUpdated, `PrepStartedEvent`, `PrepLineEvent`, `PrepFinishedEvent`
- **INotesApi** / **WorkerNotesApi** — thin wrapper over the daily-note WorkerClient methods (mirrors `IPrimeScheduleApi`). UI DTO: `DailyNoteDto(Id, Date, Text, SortOrder)`.

## Converters

- **StatusColorConverter** — task status string -> color (Queued=Blue, Running=Orange, Done=Green, Failed=Red, Manual=Gray)
- **ConnectionColorConverter** — connection state -> color (Online=Green, Offline=Red)

## Dialog Pattern

Editor dialogs use `TaskCompletionSource<bool>` — the dialog sets the result on save/cancel, and the caller awaits the TCS.

## Notes

- Context menus are on both list items and task items
- Right-click selects the item before showing the context menu
- "Run Now" CanExecute re-evaluates when worker connection state changes
- Icon gotcha: `PathIcon` fills geometry. Line-art/stroke icons must be defined as filled geometry or rendered as a stroked `Path` (e.g. `Icon.PlanDay` via the `Path.plan-icon` style); a pure stroke path used with `PathIcon` is invisible.
