feat(session): define explicit fork boundaries

This commit is contained in:
Dax Raad 2026-07-29 09:49:35 -04:00
commit fc11ed3838
29 changed files with 821 additions and 386 deletions

View file

@ -583,7 +583,7 @@ function App(props: { pair?: DialogPairCredentials }) {
return
}
void client.api.session
.fork({ sessionID: match })
.fork({ sessionID: match, boundary: { type: "through" } })
.then((result) => route.navigate({ type: "session", sessionID: result.id, prompt: startupPrompt }))
.catch(toast.error)
})
@ -596,7 +596,7 @@ function App(props: { pair?: DialogPairCredentials }) {
if (forked || !args.sessionID || !args.fork) return
forked = true
void client.api.session
.fork({ sessionID: args.sessionID })
.fork({ sessionID: args.sessionID, boundary: { type: "through" } })
.then((result) => route.navigate({ type: "session", sessionID: result.id, prompt: startupPrompt }))
.catch(toast.error)
})

View file

@ -20,24 +20,28 @@ export function DialogFork(props: { sessionID: string; messageID?: string; onMov
const fork = async (messageID?: string) => {
setPending(true)
const result = await client.api.session.fork({ sessionID: props.sessionID, messageID }).catch((error) => {
toast.show({ message: errorMessage(error), variant: "error", duration: 5000 })
return undefined
})
const result = await client.api.session
.fork({
sessionID: props.sessionID,
boundary: messageID ? { type: "before", messageID } : { type: "through" },
})
.catch((error) => {
toast.show({ message: errorMessage(error), variant: "error", duration: 5000 })
return undefined
})
if (!result) return dialog.clear()
const message = messageID ? data.session.message.get(props.sessionID, messageID) : undefined
const prompt = message?.type === "user" ? projectedPromptInput(message) : undefined
route.navigate({
sessionID: result.id,
type: "session",
prompt:
prompt
? {
...prompt,
agents: prompt.agents ?? [],
pasted: [],
}
: undefined,
prompt: prompt
? {
...prompt,
agents: prompt.agents ?? [],
pasted: [],
}
: undefined,
})
dialog.clear()
toast.show({ message: "Forked session", variant: "success", duration: 4000 })
@ -75,11 +79,7 @@ export function DialogFork(props: { sessionID: string; messageID?: string; onMov
</box>
}
>
<DialogSelect
onMove={(option) => props.onMove?.(option.value)}
title="Fork session"
options={options()}
/>
<DialogSelect onMove={(option) => props.onMove?.(option.value)} title="Fork session" options={options()} />
</Show>
)
}