feat(installer): add WPF installer/configurator project
Standalone WPF app (ClaudeDo.Installer) that handles full installation and ongoing configuration of ClaudeDo. Two modes: wizard for first run, tabbed settings panel for subsequent launches. Page-based extensibility via IInstallerPage interface — adding new config sections requires only one new class. Install pipeline: dotnet publish, deploy binaries, write configs, init DB (via SchemaInitializer from ClaudeDo.Data), register Windows Service, create shortcuts. Dark theme matching the Avalonia app (forest teal accent). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
87
src/ClaudeDo.Installer/Views/SettingsViewModel.cs
Normal file
87
src/ClaudeDo.Installer/Views/SettingsViewModel.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System.Windows;
|
||||
using ClaudeDo.Installer.Core;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace ClaudeDo.Installer.Views;
|
||||
|
||||
public partial class SettingsViewModel : ObservableObject
|
||||
{
|
||||
private readonly InstallContext _context;
|
||||
|
||||
public IReadOnlyList<IInstallerPage> Pages { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private IInstallerPage? _selectedPage;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _statusMessage;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isStatusError;
|
||||
|
||||
public SettingsViewModel(PageResolver resolver, InstallContext context)
|
||||
{
|
||||
Pages = resolver.SettingsPages;
|
||||
_context = context;
|
||||
_selectedPage = Pages.FirstOrDefault();
|
||||
|
||||
_ = LoadAllAsync();
|
||||
}
|
||||
|
||||
private async Task LoadAllAsync()
|
||||
{
|
||||
foreach (var page in Pages)
|
||||
await page.LoadAsync();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Apply()
|
||||
{
|
||||
// Validate all pages
|
||||
foreach (var page in Pages)
|
||||
{
|
||||
if (!page.Validate())
|
||||
{
|
||||
SelectedPage = page;
|
||||
StatusMessage = $"Validation failed on {page.Title}. Please fix the errors.";
|
||||
IsStatusError = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply all pages (writes to InstallContext)
|
||||
foreach (var page in Pages)
|
||||
await page.ApplyAsync();
|
||||
|
||||
// Write config files directly
|
||||
var workerCfg = new InstallerWorkerConfig
|
||||
{
|
||||
DbPath = _context.DbPath,
|
||||
SandboxRoot = _context.SandboxRoot,
|
||||
LogRoot = _context.LogRoot,
|
||||
WorktreeRootStrategy = _context.WorktreeRootStrategy,
|
||||
CentralWorktreeRoot = _context.CentralWorktreeRoot,
|
||||
QueueBackstopIntervalMs = _context.QueueBackstopIntervalMs,
|
||||
SignalRPort = _context.SignalRPort,
|
||||
ClaudeBin = _context.ClaudeBin,
|
||||
};
|
||||
workerCfg.Save();
|
||||
|
||||
var uiCfg = new InstallerAppSettings
|
||||
{
|
||||
DbPath = _context.UiDbPath,
|
||||
SignalRUrl = _context.SignalRUrl,
|
||||
};
|
||||
uiCfg.Save();
|
||||
|
||||
StatusMessage = "Settings saved successfully.";
|
||||
IsStatusError = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Close()
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user