From 59a70675511203638441424619856ee1689c5773 Mon Sep 17 00:00:00 2001 From: Allan Thraen Date: Mon, 11 May 2026 13:38:01 +0200 Subject: [PATCH] fix: stagger consecutive claude restores to avoid ~/.claude.json corruption Claude's CLI does an unlocked read-modify-write on ~/.claude.json at startup. When CodeShellManager auto-restores many claude sessions in quick succession, those writes race and can truncate or corrupt the user's profile. Insert a 2s delay between any two consecutive claude restores so each instance can settle its config write before the next one reads. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/CodeShellManager/MainWindow.xaml.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/CodeShellManager/MainWindow.xaml.cs b/src/CodeShellManager/MainWindow.xaml.cs index 34bb27c..8dee9dc 100644 --- a/src/CodeShellManager/MainWindow.xaml.cs +++ b/src/CodeShellManager/MainWindow.xaml.cs @@ -163,9 +163,16 @@ private async void OnLoaded(object sender, RoutedEventArgs e) // Launch live sessions first, then append dormant entries — keeps the // "dormant always at the bottom" invariant that SleepSession and // RebuildSidebarOrder enforce at runtime. + // Stagger consecutive claude launches: claude's CLI does an unlocked + // read-modify-write on ~/.claude.json at startup, so simultaneous + // boots can corrupt the user's profile. + bool lastWasClaude = false; foreach (var s in saved) { if (s.IsDormant) continue; + bool isClaude = ClaudeSessionService.IsClaudeCommand(s.Command); + if (isClaude && lastWasClaude) + await Task.Delay(2000); try { await LaunchSessionAsync(s, restoring: true); } catch (Exception ex) { @@ -173,6 +180,7 @@ private async void OnLoaded(object sender, RoutedEventArgs e) MessageBox.Show($"Failed to restore '{s.Name}': {ex.Message}", "Restore Error", MessageBoxButton.OK, MessageBoxImage.Warning); } + lastWasClaude = isClaude; } foreach (var s in saved) {