Skip to content

Commit 755ddbb

Browse files
feat(tui): reinsert forked message text in prompt text input box when forking session (resolves #5495) (#5545)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 701d470 commit 755ddbb

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

packages/opencode/src/cli/cmd/tui/context/route.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type HomeRoute = {
1010
export type SessionRoute = {
1111
type: "session"
1212
sessionID: string
13+
initialPrompt?: PromptInfo
1314
}
1415

1516
export type Route = HomeRoute | SessionRoute

packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Locale } from "@/util/locale"
66
import { useSDK } from "@tui/context/sdk"
77
import { useRoute } from "@tui/context/route"
88
import { useDialog } from "../../ui/dialog"
9+
import type { PromptInfo } from "@tui/component/prompt/history"
910

1011
export function DialogForkFromTimeline(props: { sessionID: string; onMove: (messageID: string) => void }) {
1112
const sync = useSync()
@@ -35,9 +36,21 @@ export function DialogForkFromTimeline(props: { sessionID: string; onMove: (mess
3536
sessionID: props.sessionID,
3637
messageID: message.id,
3738
})
39+
const parts = sync.data.part[message.id] ?? []
40+
const initialPrompt = parts.reduce(
41+
(agg, part) => {
42+
if (part.type === "text") {
43+
if (!part.synthetic) agg.input += part.text
44+
}
45+
if (part.type === "file") agg.parts.push(part)
46+
return agg
47+
},
48+
{ input: "", parts: [] as PromptInfo["parts"] },
49+
)
3850
route.navigate({
3951
sessionID: forked.data!.id,
4052
type: "session",
53+
initialPrompt,
4154
})
4255
dialog.clear()
4356
},

packages/opencode/src/cli/cmd/tui/routes/session/dialog-message.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,25 @@ export function DialogMessage(props: {
8080
sessionID: props.sessionID,
8181
messageID: props.messageID,
8282
})
83+
const initialPrompt = (() => {
84+
const msg = message()
85+
if (!msg) return undefined
86+
const parts = sync.data.part[msg.id]
87+
return parts.reduce(
88+
(agg, part) => {
89+
if (part.type === "text") {
90+
if (!part.synthetic) agg.input += part.text
91+
}
92+
if (part.type === "file") agg.parts.push(part)
93+
return agg
94+
},
95+
{ input: "", parts: [] as PromptInfo["parts"] },
96+
)
97+
})()
8398
route.navigate({
8499
sessionID: result.data!.id,
85100
type: "session",
101+
initialPrompt,
86102
})
87103
dialog.clear()
88104
},

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ export function Session() {
168168
const toast = useToast()
169169
const sdk = useSDK()
170170

171+
// Handle initial prompt from fork
172+
createEffect(() => {
173+
if (route.initialPrompt && prompt) {
174+
prompt.set(route.initialPrompt)
175+
}
176+
})
177+
171178
// Auto-navigate to whichever session currently needs permission input
172179
createEffect(() => {
173180
const currentSession = session()

0 commit comments

Comments
 (0)