diff --git a/src/ClaudeDo.Data/Wire.cs b/src/ClaudeDo.Data/Wire.cs index b38f01e2..79e75d7d 100644 --- a/src/ClaudeDo.Data/Wire.cs +++ b/src/ClaudeDo.Data/Wire.cs @@ -13,8 +13,6 @@ namespace ClaudeDo.Data.Wire; public record ActiveTaskDto(string Slot, string TaskId, DateTime StartedAt); -public record WorkerBuildInfoDto(string? BuildSha); - public record AppSettingsDto( string DefaultClaudeInstructions, string DefaultModel, diff --git a/src/ClaudeDo.Localization/locales/de.json b/src/ClaudeDo.Localization/locales/de.json index 22f5c5f5..d125bed2 100644 --- a/src/ClaudeDo.Localization/locales/de.json +++ b/src/ClaudeDo.Localization/locales/de.json @@ -720,9 +720,6 @@ "updateNow": "Jetzt aktualisieren", "dismiss": "Ausblenden" }, - "staleWorker": { - "message": "Der Worker läuft auf einem älteren Stand als der gemergte main-Branch dieses Repos — Neustart nötig, damit gemergte Änderungen wirken." - }, "externalMerge": { "banner": "Eine Claude-Session löst gerade einen Merge-Konflikt auf — bitte keine Dateien im Repository bearbeiten.", "open": "Resolver öffnen" diff --git a/src/ClaudeDo.Localization/locales/en.json b/src/ClaudeDo.Localization/locales/en.json index fb55c9bd..1ec8540e 100644 --- a/src/ClaudeDo.Localization/locales/en.json +++ b/src/ClaudeDo.Localization/locales/en.json @@ -720,9 +720,6 @@ "updateNow": "Update now", "dismiss": "Dismiss" }, - "staleWorker": { - "message": "The worker is running an older build than this repo's merged main — restart it so your merged changes take effect." - }, "externalMerge": { "banner": "A Claude session is resolving a merge conflict — don't edit files in the repository.", "open": "Open resolver" diff --git a/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs b/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs index 049e0376..44be700f 100644 --- a/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs +++ b/src/ClaudeDo.Ui/Services/Interfaces/IWorkerClient.cs @@ -183,9 +183,6 @@ public interface IWorkerClient : INotifyPropertyChanged Task GetLastPrepLogAsync(); Task> GetRecentLogsAsync(); - /// Git SHA the running worker was built from (null when offline or the build isn't stamped). - Task GetWorkerBuildInfoAsync(); - Task> GetPrimeSchedulesAsync(); Task UpsertPrimeScheduleAsync(PrimeScheduleDto dto); Task DeletePrimeScheduleAsync(Guid id); diff --git a/src/ClaudeDo.Ui/Services/WorkerClient.cs b/src/ClaudeDo.Ui/Services/WorkerClient.cs index 3f5bab8a..af0cadcc 100644 --- a/src/ClaudeDo.Ui/Services/WorkerClient.cs +++ b/src/ClaudeDo.Ui/Services/WorkerClient.cs @@ -492,9 +492,6 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC public async Task GetLastPrepLogAsync() => await TryInvokeAsync("GetLastPrepLog") ?? string.Empty; - public Task GetWorkerBuildInfoAsync() - => TryInvokeAsync("GetWorkerBuildInfo"); - public async Task> GetRecentLogsAsync() => await TryInvokeAsync>("GetRecentLogs") ?? new List(); diff --git a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs index ea21b950..0ab97a33 100644 --- a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using ClaudeDo.Data; -using ClaudeDo.Data.Git; using ClaudeDo.Data.Models; using ClaudeDo.Ui.Localization; using ClaudeDo.Ui.Services; @@ -52,7 +51,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable private readonly UpdateCheckService _updateCheck = null!; private readonly InstallerLocator _installerLocator = null!; private readonly WorkerLocator _workerLocator = null!; - private readonly GitService? _git; private readonly IDbContextFactory? _dbFactory; private readonly Func _worktreesOverviewVmFactory = () => null!; private readonly Func _weeklyReportVmFactory = () => null!; @@ -121,11 +119,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable [ObservableProperty] private string? _updateBannerLatestVersion; private bool _bannerDismissedThisSession; - // Persistent (not auto-clearing) banner: the running worker predates the selected list's - // merged HEAD, so "verified" claims made against the current process are stale. ClaudeDo-repo - // only — see RefreshStaleWorkerCheckAsync. - [ObservableProperty] private bool _isStaleWorkerBannerVisible; - // planningTaskId -> subtaskId, for unit-merge conflicts an MCP session (not the UI) started. // Kept as a dictionary so a later conflict on the same planning task updates in place instead // of piling up duplicate entries. @@ -328,8 +321,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable Func mergeVmFactory, Func repoImportVmFactory, MissionControlViewModel missionControl, - UsagePillViewModel usagePill, - GitService? git = null) + UsagePillViewModel usagePill) { Lists = lists; Tasks = tasks; Details = details; Worker = worker; MissionControl = missionControl; @@ -349,9 +341,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable _usageMonitorVmFactory = usageMonitorVmFactory; _mergeVmFactory = mergeVmFactory; _repoImportVmFactory = repoImportVmFactory; - _git = git; Lists.SelectionChanged += (_, _) => Tasks.LoadForList(Lists.SelectedList); - Lists.SelectionChanged += (_, _) => _ = RefreshStaleWorkerCheckAsync(); Tasks.SelectionChanged += (_, _) => Details.Bind(Tasks.SelectedTask, Tasks.SelectionSource); Tasks.PrepRequested += () => Details.ShowPrep(); Tasks.PropertyChanged += (_, e) => @@ -418,7 +408,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable }; Worker.OperationProgressEvent += OnOperationProgress; Worker.WorkerLogReceivedEvent += OnWorkerLogReceived; - Worker.ConnectionRestoredEvent += () => _ = RefreshStaleWorkerCheckAsync(); Worker.PlanningMergeConflictEvent += OnPlanningMergeConflict; Worker.PlanningMergeAbortedEvent += OnPlanningMergeAborted; Worker.PlanningCompletedEvent += OnPlanningMergeCompleted; @@ -471,8 +460,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable _connectTimer.Dispose(); _primeStatusTimer.Stop(); _primeStatusTimer.Dispose(); - _staleWorkerCts?.Cancel(); - _staleWorkerCts?.Dispose(); } private void RefreshBannerFromStatus() @@ -492,57 +479,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable } } - private CancellationTokenSource? _staleWorkerCts; - - // Re-evaluates the stale-worker banner for the currently selected list. Cheap (one hub call + - // up to two git subprocesses) and only ever runs for a git-backed list, so it's fine to fire on - // every selection change / reconnect rather than caching. - private async Task RefreshStaleWorkerCheckAsync() - { - _staleWorkerCts?.Cancel(); - var cts = new CancellationTokenSource(); - _staleWorkerCts = cts; - - var stale = await ComputeIsStaleWorkerAsync(Lists?.SelectedList?.WorkingDir, cts.Token); - if (cts.IsCancellationRequested) return; - IsStaleWorkerBannerVisible = stale; - } - - private async Task ComputeIsStaleWorkerAsync(string? workingDir, CancellationToken ct) - { - if (_git is null || Worker is null || string.IsNullOrWhiteSpace(workingDir)) return false; - - try - { - var buildInfo = await Worker.GetWorkerBuildInfoAsync(); - var buildSha = buildInfo?.BuildSha; - if (string.IsNullOrWhiteSpace(buildSha)) return false; - if (!await _git.IsGitRepoAsync(workingDir, ct)) return false; - - var head = await _git.RevParseHeadAsync(workingDir, ct); - var isAncestor = string.Equals(buildSha, head, StringComparison.OrdinalIgnoreCase) - ? (bool?)false // equal — never "stale" on a match, and no need to ask git - : await _git.IsAncestorAsync(workingDir, buildSha, head, ct); - return ShouldShowStaleWorkerBanner(buildSha, head, isAncestor); - } - catch - { - // Worker offline, dir no longer a repo, etc. — unknown, so stay quiet. - return false; - } - } - - // Pure decision extracted for testability. isAncestor is the tri-state result of - // `git merge-base --is-ancestor buildSha head`: true = worker predates head (stale), false = - // equal or diverged (never claim "stale" on a match or an unrelated history), null = unknown - // (e.g. buildSha isn't a commit this repo knows about — never treat "unknown" as "stale"). - internal static bool ShouldShowStaleWorkerBanner(string? buildSha, string? headSha, bool? isAncestor) - { - if (string.IsNullOrWhiteSpace(buildSha) || string.IsNullOrWhiteSpace(headSha)) return false; - if (string.Equals(buildSha, headSha, StringComparison.OrdinalIgnoreCase)) return false; - return isAncestor == true; - } - [RelayCommand] private void OpenMissionControl() { diff --git a/src/ClaudeDo.Ui/Views/MainWindow.axaml b/src/ClaudeDo.Ui/Views/MainWindow.axaml index 692860df..08462443 100644 --- a/src/ClaudeDo.Ui/Views/MainWindow.axaml +++ b/src/ClaudeDo.Ui/Views/MainWindow.axaml @@ -259,29 +259,6 @@ - - - - - -