mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-24 06:33:01 -04:00
fix(tui): preserve rollback-compatible tab state (#44277)
This commit is contained in:
committed by
GitHub
parent
da850f18da
commit
4fee1bcf3c
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user