App: build a ServiceProvider in Program.cs (AppSettings, SqliteConnectionFactory, all repositories, GitService, WorkerClient, all view-models), apply schema, then hand control to Avalonia. App.OnFrameworkInitializationCompleted resolves MainWindowViewModel from the container. Ui: - AppSettings POCO loaded from ~/.todo-app/ui.config.json (db path, hub url). - WorkerClient wraps HubConnection with auto-reconnect, exposes IsConnected and ActiveTasks plus C# events for TaskStarted/Finished/Message/Updated and WorktreeUpdated; all inbound events are marshalled to the UI thread. - ViewModels: MainWindow (lists CRUD via ListEditor dialog), TaskList (load by list, add/edit/delete, auto WakeQueue on agent+queued create), TaskItem (RunNow gated on connection + status), TaskDetail (description, result, live ndjson rolling buffer of 500 lines, worktree branch/diff with merge/keep/ discard via GitService), StatusBar, ListEditor, TaskEditor. - Views: 3-pane MainWindow (lists | tasks | detail) with GridSplitters, status bar, dialog windows for the editors. Status badges via StatusColorConverter. - Markdown rendering, folder picker, delete-confirmation, settings dialog and scroll-to-bottom on the live log are intentionally TODO -- functional scaffold only. Tests: also debounce the FIFO queue test (poll instead of Task.Delay(200)) so the assertion isn't racy when the suite runs alongside the slower git tests. 38 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 lines
807 B
C#
31 lines
807 B
C#
using System.Text.Json;
|
|
using ClaudeDo.Data;
|
|
|
|
namespace ClaudeDo.Ui;
|
|
|
|
public sealed class AppSettings
|
|
{
|
|
public string DbPath { get; set; } = "~/.todo-app/todo.db";
|
|
public string SignalRUrl { get; set; } = "http://127.0.0.1:47821/hub";
|
|
|
|
private static readonly string ConfigPath = Paths.Expand("~/.todo-app/ui.config.json");
|
|
|
|
public static AppSettings Load()
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(ConfigPath))
|
|
{
|
|
var json = File.ReadAllText(ConfigPath);
|
|
return JsonSerializer.Deserialize<AppSettings>(json,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Fall through to defaults
|
|
}
|
|
return new();
|
|
}
|
|
}
|