From 0fe313bd87747db810e3b420f8c9e5d0eab97a13 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Sat, 8 Nov 2025 20:53:11 -0500 Subject: [PATCH] tui: fix continue session navigation to wait for sync completion before redirecting Previously, the continue session navigation would immediately try to redirect to the most recent session before the sync data was fully loaded, causing navigation to fail. Now it waits for sync status to be complete before attempting the redirect, ensuring the session data is available. --- packages/opencode/src/cli/cmd/tui/app.tsx | 22 +++++++++++-------- .../opencode/src/cli/cmd/tui/context/sync.tsx | 17 ++++++++------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 194d2821..dc4eabfd 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -176,15 +176,6 @@ function App() { }) local.model.set({ providerID, modelID }, { recent: true }) } - if (args.continue) { - const match = sync.data.session.at(0)?.id - if (match) { - route.navigate({ - type: "session", - sessionID: match, - }) - } - } if (args.sessionID) { route.navigate({ type: "session", @@ -194,6 +185,19 @@ function App() { }) }) + createEffect(() => { + if (sync.status !== "complete") return + if (args.continue) { + const match = sync.data.session.at(0)?.id + if (match) { + route.navigate({ + type: "session", + sessionID: match, + }) + } + } + }) + command.register(() => [ { title: "Switch session", diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 9dc6dd7a..0dc04af2 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -22,7 +22,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ name: "Sync", init: () => { const [store, setStore] = createStore<{ - ready: boolean + status: "loading" | "partial" | "complete" provider: Provider[] agent: Agent[] command: Command[] @@ -50,7 +50,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ formatter: FormatterStatus[] }>({ config: {}, - ready: false, + status: "loading", agent: [], permission: {}, command: [], @@ -215,15 +215,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ } }) - const now = Date.now() // blocking Promise.all([ sdk.client.config.providers().then((x) => setStore("provider", x.data!.providers)), sdk.client.app.agents().then((x) => setStore("agent", x.data ?? [])), sdk.client.config.get().then((x) => setStore("config", x.data!)), ]).then(() => { - console.log("loaded in " + (Date.now() - now)) - setStore("ready", true) + if (store.status === "loading") setStore("status", "partial") }) // non-blocking @@ -238,13 +236,18 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ sdk.client.lsp.status().then((x) => setStore("lsp", x.data!)), sdk.client.mcp.status().then((x) => setStore("mcp", x.data!)), sdk.client.formatter.status().then((x) => setStore("formatter", x.data!)), - ]) + ]).then(() => { + setStore("status", "complete") + }) const result = { data: store, set: setStore, + get status() { + return store.status + }, get ready() { - return store.ready + return store.status !== "loading" }, session: { get(sessionID: string) {