diff options
| author | Dax <[email protected]> | 2026-04-18 16:20:23 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-18 20:20:23 +0000 |
| commit | a26d53151b11151a5580f11790b768ac334fa6a8 (patch) | |
| tree | f34ace57bd1b367b0e8a7b395ba1034181465584 | |
| parent | 5eaef6b758cbfb683deadb8d440a420c3c1ee1f8 (diff) | |
| download | opencode-a26d53151b11151a5580f11790b768ac334fa6a8.tar.gz opencode-a26d53151b11151a5580f11790b768ac334fa6a8.zip | |
tui: allow full-session forks from the session dialog (#23339)
| -rw-r--r-- | packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx | 25 | ||||
| -rw-r--r-- | packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 3 |
2 files changed, 20 insertions, 8 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx index 8d1e4438c..7414cefd3 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx @@ -5,11 +5,11 @@ import type { TextPart } from "@opencode-ai/sdk/v2" import { Locale } from "@/util" import { useSDK } from "@tui/context/sdk" import { useRoute } from "@tui/context/route" -import { useDialog } from "../../ui/dialog" +import { useDialog, type DialogContext } from "../../ui/dialog" import type { PromptInfo } from "@tui/component/prompt/history" import { strip } from "@tui/component/prompt/part" -export function DialogForkFromTimeline(props: { sessionID: string; onMove: (messageID: string) => void }) { +export function DialogForkFromTimeline(props: { sessionID: string; onMove: (messageID?: string) => void }) { const sync = useSync() const dialog = useDialog() const sdk = useSDK() @@ -19,9 +19,21 @@ export function DialogForkFromTimeline(props: { sessionID: string; onMove: (mess dialog.setSize("large") }) - const options = createMemo((): DialogSelectOption<string>[] => { + const options = createMemo((): DialogSelectOption<string | undefined>[] => { const messages = sync.data.message[props.sessionID] ?? [] - const result = [] as DialogSelectOption<string>[] + const fullSession = { + title: "Full session", + value: undefined, + onSelect: async (dialog: DialogContext) => { + const forked = await sdk.client.session.fork({ sessionID: props.sessionID }) + route.navigate({ + sessionID: forked.data!.id, + type: "session", + }) + dialog.clear() + }, + } satisfies DialogSelectOption<string | undefined> + const result = [] as DialogSelectOption<string | undefined>[] for (const message of messages) { if (message.role !== "user") continue const part = (sync.data.part[message.id] ?? []).find( @@ -57,9 +69,8 @@ export function DialogForkFromTimeline(props: { sessionID: string; onMove: (mess }, }) } - result.reverse() - return result + return [fullSession, ...result.reverse()] }) - return <DialogSelect onMove={(option) => props.onMove(option.value)} title="Fork from message" options={options()} /> + return <DialogSelect onMove={(option) => props.onMove(option.value)} title="Fork session" options={options()} /> } diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index ccca4d1eb..06be5dfbe 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -451,7 +451,7 @@ export function Session() { }, }, { - title: "Fork from message", + title: "Fork session", value: "session.fork", keybind: "session_fork", category: "Session", @@ -462,6 +462,7 @@ export function Session() { dialog.replace(() => ( <DialogForkFromTimeline onMove={(messageID) => { + if (!messageID) return const child = scroll.getChildren().find((child) => { return child.id === messageID }) |
