fix(app): drop archived sessions from home list right away (#44905)

Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
This commit is contained in:
Nathan Thomassin 2026-08-25 09:34:24 +02:00 committed by GitHub
parent 6bb1a76e58
commit a57230b80b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 4 deletions

View file

@ -1,8 +1,10 @@
import { describe, expect, test } from "bun:test"
import type { SessionV2Info } from "@opencode-ai/sdk/v2/client"
import { QueryClient } from "@tanstack/solid-query"
import type { Session, SessionV2Info } from "@opencode-ai/sdk/v2/client"
import {
applyHomeSessionEvent,
appendHomeSessionEvent,
createHomeSessionIndexCache,
HOME_V2_SESSION_PAGE_LIMIT,
loadHomeSessionIndex,
homeSessionIndexSessions,
@ -151,4 +153,33 @@ describe("Home V2 session index", () => {
expect(homeSessionIndexRefresh("global.disposed", true).refetch).toBe(true)
expect(homeSessionIndexRefresh("session.next.moved", true).refetch).toBe(true)
})
test("removes a session from the loaded Home index", () => {
const queryClient = new QueryClient()
const cache = createHomeSessionIndexCache(queryClient, "server")
const sessions = [
{ id: "a", time: { created: 1, updated: 1 } },
{ id: "b", time: { created: 1, updated: 1 } },
] as Session[]
queryClient.setQueryData(cache.indexKey, { sessions, eventSequence: 0 })
cache.remove("a")
const index = queryClient.getQueryData<{ sessions: Session[] }>(cache.indexKey)
expect(index?.sessions.map((item) => item.id)).toEqual(["b"])
})
test("keeps the session out of the Home list when the index is not mounted", () => {
const queryClient = new QueryClient()
const cache = createHomeSessionIndexCache(queryClient, "server")
const sessions = [
{ id: "a", time: { created: 1, updated: 1 } },
{ id: "b", time: { created: 1, updated: 1 } },
] as Session[]
cache.remove("a")
expect(queryClient.getQueryData(cache.indexKey)).toBeUndefined()
expect(cache.sessions({ sessions, eventSequence: 0 }, undefined).map((item) => item.id)).toEqual(["b"])
})
})

View file

@ -85,6 +85,7 @@ export function createHomeSessionIndexCache(queryClient: QueryClient, server: st
const indexKey = homeSessionIndexKey(server)
const eventsKey = homeSessionEventsKey(server)
let connected = false
const removed = new Set<string>()
return {
indexKey,
@ -97,7 +98,8 @@ export function createHomeSessionIndexCache(queryClient: QueryClient, server: st
queryClient.setQueryData<HomeSessionEvents>(eventsKey, (current) => trimHomeSessionEvents(current, sequence))
},
sessions(index: HomeSessionIndex | undefined, events: HomeSessionEvents | undefined) {
return homeSessionIndexSessions(index, events)
const sessions = homeSessionIndexSessions(index, events)
return removed.size === 0 ? sessions : sessions.filter((session) => !removed.has(session.id))
},
apply(event: HomeSessionEvent) {
if (!queryClient.getQueryState(indexKey)) return
@ -116,6 +118,16 @@ export function createHomeSessionIndexCache(queryClient: QueryClient, server: st
}
queryClient.setQueryData<HomeSessionEvents>(eventsKey, { sequence: next.sequence, entries: [] })
},
remove(sessionID: string) {
removed.add(sessionID)
if (!queryClient.getQueryState(indexKey)) return
queryClient.setQueryData<HomeSessionIndex>(indexKey, (index) => {
if (!index) return index
const at = index.sessions.findIndex((session) => session.id === sessionID)
if (at === -1) return index
return { ...index, sessions: index.sessions.toSpliced(at, 1) }
})
},
refresh(event: Event["type"]) {
const result = homeSessionIndexRefresh(event, connected)
connected = result.connected

View file

@ -219,13 +219,15 @@ export function createHomeSessionsController(home: HomeController) {
directory: session.directory,
time: { archived: Date.now() },
}),
remove: () =>
remove: () => {
setStore(
produce((draft) => {
const match = Binary.search(draft.session, session.id, (item) => item.id)
if (match.found) draft.session.splice(match.index, 1)
}),
),
)
homeSessions().remove(session.id)
},
onError: (cause) =>
showToast({
title: language.t("common.requestFailed"),

View file

@ -3,6 +3,7 @@ import { produce } from "solid-js/store"
import { notifySessionTabsRemoved } from "@/components/titlebar-session-events"
import { useLanguage } from "@/context/language"
import { useSDK } from "@/context/sdk"
import { useServerSync } from "@/context/server-sync"
import { useSync } from "@/context/sync"
import { useTabs } from "@/context/tabs"
import { errorMessage } from "@/pages/layout/helpers"
@ -15,6 +16,7 @@ export function useSessionArchive() {
const navigate = useNavigate()
const sdk = useSDK()
const sync = useSync()
const serverSync = useServerSync()
const tabs = useTabs()
const { params } = useSessionKey()
@ -56,6 +58,7 @@ export function useSessionArchive() {
}),
)
sync().session.evict(sessionID)
serverSync().homeSessions.remove(sessionID)
navigateAfterRemoval(sessionID, session.parentID, nextSession?.id)
notifySessionTabsRemoved({ directory: sdk().directory, sessionIDs: [sessionID] })
})