From 545b86587de6e8e33cfb41df1258a245a8abcf29 Mon Sep 17 00:00:00 2001 From: usrnk1 <7547651+usrnk1@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:36:34 +0200 Subject: [PATCH] feat(app): detect prior server activity for layout transition --- packages/app/src/context/server.test.ts | 18 ++++++++++++++++++ packages/app/src/context/server.tsx | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/app/src/context/server.test.ts b/packages/app/src/context/server.test.ts index d78880ecf1..87e2c0edf1 100644 --- a/packages/app/src/context/server.test.ts +++ b/packages/app/src/context/server.test.ts @@ -3,6 +3,7 @@ import { createRoot, createSignal } from "solid-js" import { createStore } from "solid-js/store" import { createServerProjects, + hasPersistedServerData, migrateCanonicalLocalServerState, nextServerAfterRemoval, resolveServerList, @@ -61,6 +62,23 @@ describe("resolveServerList", () => { }) }) +describe("hasPersistedServerData", () => { + const empty = () => ({ list: [], projects: {}, lastProject: {}, recentlyClosed: {} }) + + test("ignores a blank persisted server store", () => { + expect(hasPersistedServerData(empty())).toBe(false) + }) + + test("recognizes configured servers and remembered project activity", () => { + expect(hasPersistedServerData({ ...empty(), list: ["https://example.com"] })).toBe(true) + expect(hasPersistedServerData({ ...empty(), projects: { local: [{ worktree: "/code", expanded: true }] } })).toBe( + true, + ) + expect(hasPersistedServerData({ ...empty(), lastProject: { local: "/code" } })).toBe(true) + expect(hasPersistedServerData({ ...empty(), recentlyClosed: { local: ["/code"] } })).toBe(true) + }) +}) + test("treats WSL sidecars as remote server connections", () => { expect( ServerConnection.local({ diff --git a/packages/app/src/context/server.tsx b/packages/app/src/context/server.tsx index 450129f458..d6ba573990 100644 --- a/packages/app/src/context/server.tsx +++ b/packages/app/src/context/server.tsx @@ -12,6 +12,7 @@ type ServerProjectState = { lastProject: Record recentlyClosed: Record } +type PersistedServerState = ServerProjectState & { list: StoredServer[] } const HEALTH_POLL_INTERVAL_MS = 10_000 // The store retains more history than is displayed. Consumers filter recently closed entries // against the live project list (dropping deleted projects) and then cap the visible count via @@ -178,6 +179,13 @@ export function resolveServerList(input: { return [...deduped.values()] } +export function hasPersistedServerData(store: PersistedServerState) { + if (store.list.length > 0) return true + if (Object.values(store.projects).some((projects) => projects.length > 0)) return true + if (Object.values(store.lastProject).some(Boolean)) return true + return Object.values(store.recentlyClosed).some((projects) => projects.length > 0) +} + export namespace ServerConnection { type Base = { displayName?: string; label?: string } @@ -331,10 +339,12 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext( () => allServers().find((s) => ServerConnection.key(s) === state.active) ?? allServers()[0], ) const isLocal = createMemo(() => ServerConnection.local(current())) + const hasPersistedData = createMemo(() => hasPersistedServerData(store)) return { ready: isReady, isLocal, + hasPersistedData, get key() { return state.active },