From ead798dcf212ab9f85514dc82eca6c9e8141fae1 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 29 Apr 2026 19:19:30 -0700 Subject: [PATCH] fix(tui): preserve working set on refresh --- internal/cli/tui.go | 3 +++ internal/cli/tui_test.go | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/internal/cli/tui.go b/internal/cli/tui.go index 1fca59e..5094733 100644 --- a/internal/cli/tui.go +++ b/internal/cli/tui.go @@ -2783,6 +2783,9 @@ func (m *clusterBrowserModel) applyClusterRefresh(clusters []store.ClusterSummar if clusters == nil { clusters = []store.ClusterSummary{} } + if m.payload.Limit <= 0 && len(clusters) > 0 && len(clusters) < len(m.allClusters) { + clusters = mergeClusterSummaries(clusters, m.allClusters) + } m.detailCache = map[int64]store.ClusterDetail{} m.allClusters = append([]store.ClusterSummary(nil), clusters...) m.payload.Clusters = append([]store.ClusterSummary(nil), clusters...) diff --git a/internal/cli/tui_test.go b/internal/cli/tui_test.go index eca285b..58748c7 100644 --- a/internal/cli/tui_test.go +++ b/internal/cli/tui_test.go @@ -693,6 +693,49 @@ func TestMergeClusterSummariesKeepsPrimaryView(t *testing.T) { } } +func TestTUIRefreshPreservesUnlimitedWorkingSet(t *testing.T) { + model := newClusterBrowserModel(context.Background(), nil, 0, clusterBrowserPayload{ + Repository: "openclaw/openclaw", + Sort: "recent", + Clusters: []store.ClusterSummary{ + {ID: 1, Status: "active", MemberCount: 5, UpdatedAt: "2026-04-27T00:00:00Z"}, + {ID: 2, Status: "active", MemberCount: 5, UpdatedAt: "2026-04-27T00:00:00Z"}, + {ID: 3, Status: "active", MemberCount: 5, UpdatedAt: "2026-04-27T00:00:00Z"}, + }, + }) + + model.applyClusterRefresh([]store.ClusterSummary{ + {ID: 2, Status: "active", MemberCount: 7, UpdatedAt: "2026-04-28T00:00:00Z"}, + }, 2) + + if len(model.payload.Clusters) != 3 { + t.Fatalf("refresh collapsed working set to %d clusters: %#v", len(model.payload.Clusters), model.payload.Clusters) + } + if model.payload.Clusters[0].ID != 2 || model.payload.Clusters[0].MemberCount != 7 { + t.Fatalf("fresh cluster update was not preserved first: %#v", model.payload.Clusters) + } +} + +func TestTUIRefreshHonorsExplicitClusterLimit(t *testing.T) { + model := newClusterBrowserModel(context.Background(), nil, 0, clusterBrowserPayload{ + Repository: "openclaw/openclaw", + Sort: "recent", + Limit: 1, + Clusters: []store.ClusterSummary{ + {ID: 1, Status: "active", MemberCount: 5, UpdatedAt: "2026-04-27T00:00:00Z"}, + {ID: 2, Status: "active", MemberCount: 5, UpdatedAt: "2026-04-27T00:00:00Z"}, + }, + }) + + model.applyClusterRefresh([]store.ClusterSummary{ + {ID: 2, Status: "active", MemberCount: 7, UpdatedAt: "2026-04-28T00:00:00Z"}, + }, 2) + + if len(model.payload.Clusters) != 1 || model.payload.Clusters[0].ID != 2 { + t.Fatalf("explicit limit was not honored: %#v", model.payload.Clusters) + } +} + func TestTUIHideClosedUsesLoadedWorkingSet(t *testing.T) { clusters := sampleTUIClusters() clusters[0].Status = "closed"