fix(tui): preserve rollback-compatible tab state (#44277)

This commit is contained in:
opencode-agent[bot]
2026-08-23 00:16:03 +00:00
committed by GitHub
parent da850f18da
commit 4fee1bcf3c
2 changed files with 10 additions and 9 deletions
+5 -4
View File
@@ -29,8 +29,8 @@ import {
type TabsState = {
tabs: SessionTab[]
// Read only long enough to remove the former client-owned state from persisted tab files.
unread?: Record<string, unknown>
// Kept empty for rollback compatibility with clients that still read this field.
unread: Record<string, unknown>
}
type PersistedState = {
@@ -43,7 +43,7 @@ type ScrollAnchor = {
screenY: number
}
const empty = (): TabsState => ({ tabs: [] })
const empty = (): TabsState => ({ tabs: [], unread: {} })
// Deliberately after connect settles: the visible session's mount syncs win the first slots.
const TAB_PREFETCH_DELAY = 300
@@ -128,6 +128,7 @@ export const { use: useSessionTabs, provider: SessionTabsProvider } = createSimp
const sessionID = root(tab.sessionID)
return openSessionTab(tabs, { sessionID, title: title(sessionID, tab.title) })
}, []),
unread: {},
})
const current = () => (route.data.type === "session" ? root(route.data.sessionID) : undefined)
const newTab = createMemo((open = false) => {
@@ -219,7 +220,7 @@ export const { use: useSessionTabs, provider: SessionTabsProvider } = createSimp
update((draft) => {
const next = normalize(draft)
draft.tabs = next.tabs
delete draft.unread
draft.unread = next.unread
})
})
@@ -265,10 +265,10 @@ test("stores session tabs for the current working directory by default", async (
const file = path.join(setup.state, "test", "tui", "tabs.json")
await wait(() => Bun.file(file).size > 0)
const stored = await Bun.file(file).json()
expect(stored.global).toEqual({ tabs: [] })
expect(stored.global).toEqual({ tabs: [], unread: {} })
expect(Object.keys(stored.cwd)).toEqual([directory])
expect(stored.cwd[directory].tabs.map((tab: { sessionID: string }) => tab.sessionID)).toEqual(["first"])
expect(stored.cwd[directory]).not.toHaveProperty("unread")
expect(stored.cwd[directory].unread).toEqual({})
} finally {
await setup.destroy()
}
@@ -336,14 +336,14 @@ test("acknowledges viewed sessions even when tabs are disabled", async () => {
}
})
test("purges legacy persisted unread records", async () => {
test("empties legacy persisted unread records for rollback compatibility", async () => {
const setup = await renderSessionTabs("first", { persisted: ["first"] })
try {
const file = path.join(setup.state, "test", "tui", "tabs.json")
// Normalize rewrites the active scope; the legacy record must not survive it.
// Normalize rewrites the active scope; legacy values must not survive, but older clients require the field.
await wait(async () => {
const stored = await Bun.file(file).json()
return !("unread" in stored.cwd[directory])
return Object.keys(stored.cwd[directory].unread).length === 0
})
} finally {
await setup.destroy()