diff --git a/src/Netclaw.Cli.Tests/Tui/InitExistingInstallPageTests.cs b/src/Netclaw.Cli.Tests/Tui/InitExistingInstallPageTests.cs index 75a852eb5..d9261e072 100644 --- a/src/Netclaw.Cli.Tests/Tui/InitExistingInstallPageTests.cs +++ b/src/Netclaw.Cli.Tests/Tui/InitExistingInstallPageTests.cs @@ -42,7 +42,7 @@ public async Task ProgressScreen_RendersQueuedUpdates_AndOnlyCtrlQExits() (_, _) => Task.FromResult(new DaemonResult(true, "Daemon stopped.")), path => { - if (path == _paths.BasePath) + if (path == _paths.ConfigDirectory) { deleteStarted.TrySetResult(); releaseDelete.Task.GetAwaiter().GetResult(); diff --git a/src/Netclaw.Cli.Tests/Tui/InitExistingInstallViewModelTests.cs b/src/Netclaw.Cli.Tests/Tui/InitExistingInstallViewModelTests.cs index 77ee26868..7ca481799 100644 --- a/src/Netclaw.Cli.Tests/Tui/InitExistingInstallViewModelTests.cs +++ b/src/Netclaw.Cli.Tests/Tui/InitExistingInstallViewModelTests.cs @@ -103,6 +103,9 @@ public async Task FullReset_AfterBothConfirmations_DeletesEverything() { File.WriteAllText(_paths.NetclawConfigPath, "{}"); File.WriteAllText(_paths.SqliteDbPath, "db"); + // bin/ holds the installed binaries; a full reset must purge data but keep it. + var binaryPath = Path.Combine(_paths.BinDirectory, "netclaw"); + File.WriteAllText(binaryPath, "binary"); var vm = Create(); string? route = null; @@ -113,7 +116,9 @@ public async Task FullReset_AfterBothConfirmations_DeletesEverything() Select(vm, 1); // Yes → perform await WaitForProgressAsync(vm, 3); - Assert.False(Directory.Exists(_paths.BasePath)); + Assert.False(Directory.Exists(_paths.ConfigDirectory), "Config should be purged."); + Assert.False(File.Exists(_paths.SqliteDbPath), "Memory db should be purged."); + Assert.True(File.Exists(binaryPath), "Installed binaries in bin/ must survive a full reset."); await CompleteResetAsync(vm); Assert.Equal(InitExistingInstallViewModel.WizardRoute, route); } @@ -292,7 +297,7 @@ public async Task Dispose_WhileDeleteIsRunning_CancelsCompletionNavigation() var releaseDelete = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var vm = Create(DaemonStopped, path => { - if (path == _paths.BasePath) + if (path == _paths.ConfigDirectory) { deleteStarted.TrySetResult(); releaseDelete.Task.GetAwaiter().GetResult(); @@ -350,7 +355,7 @@ public async Task ResetFailure_AfterBlockedQuit_ClearsQuitDisabledStatus() var releaseDelete = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var vm = Create(DaemonStopped, path => { - if (path == _paths.BasePath) + if (path == _paths.ConfigDirectory) { deleteStarted.TrySetResult(); releaseDelete.Task.GetAwaiter().GetResult(); diff --git a/src/Netclaw.Cli/Tui/InitExistingInstallViewModel.cs b/src/Netclaw.Cli/Tui/InitExistingInstallViewModel.cs index 86b5d3012..ba43466cc 100644 --- a/src/Netclaw.Cli/Tui/InitExistingInstallViewModel.cs +++ b/src/Netclaw.Cli/Tui/InitExistingInstallViewModel.cs @@ -236,7 +236,19 @@ private async Task RunResetAsync(CancellationToken ct) if (_scope == ResetScopeKind.Full) { - _deleteDirectory(_paths.BasePath); + // Purge everything under BasePath except bin/ — the installed binaries + // live there and deleting them would brick the CLI mid-reset. + foreach (var entry in Directory.GetDirectories(_paths.BasePath)) + { + var name = Path.GetFileName(entry); + if (string.Equals(name, "bin", StringComparison.OrdinalIgnoreCase)) + continue; + + _deleteDirectory(entry); + } + + foreach (var file in Directory.GetFiles(_paths.BasePath)) + File.Delete(file); } else {