diff --git a/src/ClaudeDo.Installer/Core/UninstallRunner.cs b/src/ClaudeDo.Installer/Core/UninstallRunner.cs index 39809bb..e49f1f9 100644 --- a/src/ClaudeDo.Installer/Core/UninstallRunner.cs +++ b/src/ClaudeDo.Installer/Core/UninstallRunner.cs @@ -17,7 +17,7 @@ public sealed class UninstallRunner _stopService = stopService; } - public async Task RunAsync(IProgress progress, CancellationToken ct) + public async Task RunAsync(bool removeAppData, IProgress progress, CancellationToken ct) { // 1) Validate install dir up front — refuse obviously unsafe paths. // Prevents Directory.Delete(recursive:true) from wiping C:\ or C:\Program Files\. @@ -67,13 +67,16 @@ public sealed class UninstallRunner failures.Add($"install dir ({_context.InstallDirectory}): {err}"); } - // 6) Delete ~/.todo-app (config + DB + logs) — user opted into full removal. - var appData = Paths.AppDataRoot(); - if (Directory.Exists(appData)) + // 6) Delete ~/.todo-app (config + DB + logs) — only if user opted in. + if (removeAppData) { - progress.Report($"Deleting {appData}..."); - if (!TryDeleteDir(appData, out var err)) - failures.Add($"app data ({appData}): {err}"); + var appData = Paths.AppDataRoot(); + if (Directory.Exists(appData)) + { + progress.Report($"Deleting {appData}..."); + if (!TryDeleteDir(appData, out var err)) + failures.Add($"app data ({appData}): {err}"); + } } // 7) If we were launched from inside the install dir (Apps & Features case), diff --git a/src/ClaudeDo.Installer/Views/SettingsViewModel.cs b/src/ClaudeDo.Installer/Views/SettingsViewModel.cs index 40670c8..659c5f2 100644 --- a/src/ClaudeDo.Installer/Views/SettingsViewModel.cs +++ b/src/ClaudeDo.Installer/Views/SettingsViewModel.cs @@ -29,6 +29,9 @@ public partial class SettingsViewModel : ObservableObject [ObservableProperty] private string _versionLabel = ""; + [ObservableProperty] + private bool _removeAppData; + public SettingsViewModel( PageResolver resolver, InstallContext context, @@ -133,8 +136,12 @@ public partial class SettingsViewModel : ObservableObject [RelayCommand] private async Task Uninstall() { + var dataNote = RemoveAppData + ? "This will remove ClaudeDo AND delete all of your tasks, configuration, and database.\n\nContinue?" + : "This will remove ClaudeDo. Your tasks, configuration, and database in ~/.todo-app will be kept.\n\nContinue?"; + var confirm = MessageBox.Show( - "This will remove ClaudeDo AND delete all of your tasks, configuration, and database.\n\nContinue?", + dataNote, "Uninstall ClaudeDo", MessageBoxButton.YesNo, MessageBoxImage.Warning); @@ -142,7 +149,7 @@ public partial class SettingsViewModel : ObservableObject if (confirm != MessageBoxResult.Yes) return; var progress = new Progress(msg => StatusMessage = msg); - var r = await _uninstallRunner.RunAsync(progress, CancellationToken.None); + var r = await _uninstallRunner.RunAsync(RemoveAppData, progress, CancellationToken.None); if (!r.Success) { diff --git a/src/ClaudeDo.Installer/Views/SettingsWindow.xaml b/src/ClaudeDo.Installer/Views/SettingsWindow.xaml index 11a2596..d1ef6f7 100644 --- a/src/ClaudeDo.Installer/Views/SettingsWindow.xaml +++ b/src/ClaudeDo.Installer/Views/SettingsWindow.xaml @@ -69,6 +69,7 @@ + @@ -88,14 +89,17 @@ -