refactor(ui): remove the stale-worker banner

The banner compared the running worker's build SHA against the
selected list's HEAD via a git ancestor check on every list switch
and reconnect. It added a git-rev-parse MSBuild target, a hub call,
and a poll loop for a corner case that hasn't come up in practice —
not worth the moving parts.
This commit is contained in:
mika kuns
2026-09-02 09:59:39 +02:00
parent b6e5876b07
commit 6be62f02cc
13 changed files with 1 additions and 221 deletions
@@ -1,47 +0,0 @@
using ClaudeDo.Ui.ViewModels;
using Xunit;
namespace ClaudeDo.Ui.Tests;
public class StaleWorkerBannerDecisionTests
{
private const string ShaA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
private const string ShaB = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
[Fact]
public void True_when_build_is_a_strict_ancestor_of_head()
{
Assert.True(IslandsShellViewModel.ShouldShowStaleWorkerBanner(ShaA, ShaB, isAncestor: true));
}
[Fact]
public void False_when_build_equals_head_even_if_ancestor_check_says_true()
{
Assert.False(IslandsShellViewModel.ShouldShowStaleWorkerBanner(ShaA, ShaA, isAncestor: true));
}
[Fact]
public void False_when_ancestor_check_says_no()
{
Assert.False(IslandsShellViewModel.ShouldShowStaleWorkerBanner(ShaA, ShaB, isAncestor: false));
}
[Fact]
public void False_when_ancestor_check_is_unknown()
{
// Unknown must never be treated as stale.
Assert.False(IslandsShellViewModel.ShouldShowStaleWorkerBanner(ShaA, ShaB, isAncestor: null));
}
[Fact]
public void False_when_build_sha_missing()
{
Assert.False(IslandsShellViewModel.ShouldShowStaleWorkerBanner(null, ShaB, isAncestor: true));
}
[Fact]
public void False_when_head_sha_missing()
{
Assert.False(IslandsShellViewModel.ShouldShowStaleWorkerBanner(ShaA, null, isAncestor: true));
}
}
@@ -170,8 +170,6 @@ public abstract class StubWorkerClient : IWorkerClient
public virtual Task DeleteDailyNoteAsync(string id) => Task.CompletedTask;
public string LastPrepLog = "";
public virtual Task<string> GetLastPrepLogAsync() => Task.FromResult(LastPrepLog);
public WorkerBuildInfoDto? WorkerBuildInfo;
public virtual Task<WorkerBuildInfoDto?> GetWorkerBuildInfoAsync() => Task.FromResult(WorkerBuildInfo);
public virtual Task RefineTaskAsync(string taskId) => Task.CompletedTask;
public virtual Task<ClaudeBinDto?> GetClaudeBinAsync() => Task.FromResult<ClaudeBinDto?>(null);
@@ -1,36 +0,0 @@
using ClaudeDo.Worker.Hub;
using Xunit;
namespace ClaudeDo.Worker.Tests.Hub;
public sealed class WorkerBuildInfoHubTests
{
[Theory]
[InlineData(null, null)]
[InlineData("", null)]
[InlineData("1.2.3", null)]
[InlineData("1.2.3+", null)]
[InlineData("1.2.3+abc1234", "abc1234")]
// MinVer's own pre-release metadata can already contain a '+' (e.g. "+devsha"); our
// SourceRevisionId is appended last, so only the segment after the LAST '+' is authoritative.
[InlineData("0.0.0-alpha.0.4+devsha+f5b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9", "f5b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9")]
public void ParseBuildSha_ExtractsSegmentAfterLastPlus(string? informationalVersion, string? expected)
{
Assert.Equal(expected, WorkerHub.ParseBuildSha(informationalVersion));
}
[Fact]
public void GetWorkerBuildInfo_ReturnsDto()
{
var hub = new WorkerHub(
null!, null!, null!, null!, null!, null!,
null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!,
null!, new ClaudeDo.Worker.Online.OnlineInboxConfig(), new ClaudeDo.Worker.OnlineRefreshTokenStore(new ClaudeDo.Worker.DpapiTokenStore("unused.token")),
new ClaudeDo.Worker.Runner.PendingQuestionRegistry(), null!);
// No assertion on the actual SHA value (depends on the build environment) — just that
// the call doesn't throw and always returns a DTO, never null.
var info = hub.GetWorkerBuildInfo();
Assert.NotNull(info);
}
}
@@ -159,7 +159,6 @@ sealed class FakeWorkerClient : IWorkerClient
public Task UpdateDailyNoteAsync(string id, string text) => Task.CompletedTask;
public Task DeleteDailyNoteAsync(string id) => Task.CompletedTask;
public Task<string> GetLastPrepLogAsync() => Task.FromResult(string.Empty);
public Task<WorkerBuildInfoDto?> GetWorkerBuildInfoAsync() => Task.FromResult<WorkerBuildInfoDto?>(null);
public Task RefineTaskAsync(string taskId) => Task.CompletedTask;
public Task<ClaudeBinDto?> GetClaudeBinAsync() => Task.FromResult<ClaudeBinDto?>(null);
public Task<ClaudeBinDto?> SetClaudeBinAsync(string? value) => Task.FromResult<ClaudeBinDto?>(null);