diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 5cb249da7c..8256217d05 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -247,21 +247,12 @@ function App() { }) local.model.set({ providerID, modelID }, { recent: true }) } - if (args.sessionID) { - if (args.fork) { - sdk.client.session.fork({ sessionID: args.sessionID }).then((result) => { - if (result.data?.id) { - route.navigate({ type: "session", sessionID: result.data.id }) - } else { - toast.show({ message: "Failed to fork session", variant: "error" }) - } - }) - } else { - route.navigate({ - type: "session", - sessionID: args.sessionID, - }) - } + // Handle --session without --fork immediately (fork is handled in createEffect below) + if (args.sessionID && !args.fork) { + route.navigate({ + type: "session", + sessionID: args.sessionID, + }) } }) }) @@ -289,6 +280,22 @@ function App() { } }) + // Handle --session with --fork: wait for sync to be fully complete before forking + // (session list loads in non-blocking phase for --session, so we must wait for "complete" + // to avoid a race where reconcile overwrites the newly forked session) + let forked = false + createEffect(() => { + if (forked || sync.status !== "complete" || !args.sessionID || !args.fork) return + forked = true + sdk.client.session.fork({ sessionID: args.sessionID }).then((result) => { + if (result.data?.id) { + route.navigate({ type: "session", sessionID: result.data.id }) + } else { + toast.show({ message: "Failed to fork session", variant: "error" }) + } + }) + }) + createEffect( on( () => sync.status === "complete" && sync.data.provider.length === 0,