6.9 KiB
6.9 KiB
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(extendsObservableObject)
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
InheritedBadgecontrol +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 onIsTaskDetailVisible— 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 taskLogand the prepPrepLog. - SettingsModalView — Prime Claude tab contains a
DailyPrepMaxTasksnumeric 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 hostsNotesEditorViewModel. Also gains daily-prep mode:IsPrepMode,PrepLog(ObservableCollection<LogLineViewModel>),ShowPrep(),PlanDayCommand(callsRunDailyPrepNowAsync),ShowPrepEmptyState, and computedIsTaskDetailVisible(=!IsNotesMode && !IsPrepMode). Subscribes toPrepStartedEvent,PrepLineEvent,PrepFinishedEvent; streams lines intoPrepLogviaStreamLineFormatter(same path as task logs). On open, if log is empty and no run is in progress, loads persisted last run viaGetLastPrepLogAsync. The WorkConsole Session tab gains a mergeability indicator (MergePreviewPresenter) and a single-task Merge button; indicator is populated viaPreviewMergeAsyncand displayed for tasks in WaitingForReview. - TasksIslandViewModel gains a pinned "Notes" pseudo-row (
ShowNotesRow,OpenNotesCommand,NotesRequestedevent) that switches the Details island to notes mode. Also gainsIsMyDayList(true when selected list issmart:my-day),ShowPrepLogCommand(raisesPrepRequestedevent → shell callsDetails.ShowPrep()), andClearDayCommand(callsClearMyDayAsync).
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:
PathIconfills geometry. Line-art/stroke icons must be defined as filled geometry or rendered as a strokedPath(e.g.Icon.PlanDayvia thePath.plan-iconstyle); a pure stroke path used withPathIconis invisible.