Procházet zdrojové kódy

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>
Ariane Emory před 3 měsíci
rodič
revize
755ddbb223

+ 1 - 0
packages/opencode/src/cli/cmd/tui/context/route.tsx

@@ -10,6 +10,7 @@ export type HomeRoute = {
 export type SessionRoute = {
 export type SessionRoute = {
   type: "session"
   type: "session"
   sessionID: string
   sessionID: string
+  initialPrompt?: PromptInfo
 }
 }
 
 
 export type Route = HomeRoute | SessionRoute
 export type Route = HomeRoute | SessionRoute

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

@@ -6,6 +6,7 @@ import { Locale } from "@/util/locale"
 import { useSDK } from "@tui/context/sdk"
 import { useSDK } from "@tui/context/sdk"
 import { useRoute } from "@tui/context/route"
 import { useRoute } from "@tui/context/route"
 import { useDialog } from "../../ui/dialog"
 import { useDialog } from "../../ui/dialog"
+import type { PromptInfo } from "@tui/component/prompt/history"
 
 
 export function DialogForkFromTimeline(props: { sessionID: string; onMove: (messageID: string) => void }) {
 export function DialogForkFromTimeline(props: { sessionID: string; onMove: (messageID: string) => void }) {
   const sync = useSync()
   const sync = useSync()
@@ -35,9 +36,21 @@ export function DialogForkFromTimeline(props: { sessionID: string; onMove: (mess
             sessionID: props.sessionID,
             sessionID: props.sessionID,
             messageID: message.id,
             messageID: message.id,
           })
           })
+          const parts = sync.data.part[message.id] ?? []
+          const initialPrompt = parts.reduce(
+            (agg, part) => {
+              if (part.type === "text") {
+                if (!part.synthetic) agg.input += part.text
+              }
+              if (part.type === "file") agg.parts.push(part)
+              return agg
+            },
+            { input: "", parts: [] as PromptInfo["parts"] },
+          )
           route.navigate({
           route.navigate({
             sessionID: forked.data!.id,
             sessionID: forked.data!.id,
             type: "session",
             type: "session",
+            initialPrompt,
           })
           })
           dialog.clear()
           dialog.clear()
         },
         },

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

@@ -80,9 +80,25 @@ export function DialogMessage(props: {
               sessionID: props.sessionID,
               sessionID: props.sessionID,
               messageID: props.messageID,
               messageID: props.messageID,
             })
             })
+            const initialPrompt = (() => {
+              const msg = message()
+              if (!msg) return undefined
+              const parts = sync.data.part[msg.id]
+              return parts.reduce(
+                (agg, part) => {
+                  if (part.type === "text") {
+                    if (!part.synthetic) agg.input += part.text
+                  }
+                  if (part.type === "file") agg.parts.push(part)
+                  return agg
+                },
+                { input: "", parts: [] as PromptInfo["parts"] },
+              )
+            })()
             route.navigate({
             route.navigate({
               sessionID: result.data!.id,
               sessionID: result.data!.id,
               type: "session",
               type: "session",
+              initialPrompt,
             })
             })
             dialog.clear()
             dialog.clear()
           },
           },

+ 7 - 0
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -168,6 +168,13 @@ export function Session() {
   const toast = useToast()
   const toast = useToast()
   const sdk = useSDK()
   const sdk = useSDK()
 
 
+  // Handle initial prompt from fork
+  createEffect(() => {
+    if (route.initialPrompt && prompt) {
+      prompt.set(route.initialPrompt)
+    }
+  })
+
   // Auto-navigate to whichever session currently needs permission input
   // Auto-navigate to whichever session currently needs permission input
   createEffect(() => {
   createEffect(() => {
     const currentSession = session()
     const currentSession = session()