fix(sessions): fall back when lastDirectory is a deleted worktree
New chats inherited a persisted lastDirectory even after that worktree was removed, so the first message saved but the prompt never started. Validate the implicit draft directory, fall back to the active project only when OpenCode confirms the path is missing, and leave explicit worktree targets and unknown probes unchanged. Co-authored-by: serkraser <serkraser@gmail.com>
This commit is contained in:
co-authored by
serkraser
parent
6b1e677aaf
commit
90e79b04a4
@@ -603,6 +603,63 @@ const waitForWorktreeBootstrapIfConfigured = async (directory: string | null, pr
|
||||
}
|
||||
}
|
||||
|
||||
const resolveActiveProjectDirectory = (draft: NewSessionDraftState): string | null => {
|
||||
const projectsState = useProjectsStore.getState()
|
||||
return normalizePath(
|
||||
projectsState.getActiveProject()?.path
|
||||
?? (draft.selectedProjectId
|
||||
? projectsState.projects.find((project) => project.id === draft.selectedProjectId)?.path
|
||||
: null)
|
||||
?? null,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular new-chat drafts inherit the persisted current/last directory. If that
|
||||
* path is confirmed missing (deleted worktree), fall back to the active project.
|
||||
* Explicit worktree targets, in-flight worktree creation, and unknown/offline
|
||||
* probes stay unchanged so a temporary outage cannot rewrite the destination.
|
||||
*/
|
||||
const resolveCreatableDraftDirectory = async (
|
||||
draft: NewSessionDraftState,
|
||||
requestedDirectory: string | null | undefined,
|
||||
): Promise<{ status: "ok"; directory: string | null | undefined } | { status: "aborted" }> => {
|
||||
const directory = requestedDirectory ?? opencodeClient.getDirectory() ?? null
|
||||
const isRecoverableDraftDirectory =
|
||||
draft.open
|
||||
&& draft.preserveDirectoryOverride !== true
|
||||
&& !draft.pendingWorktreeRequestId
|
||||
&& !draft.bootstrapPendingDirectory
|
||||
&& normalizePath(draft.directoryOverride) === normalizePath(directory)
|
||||
|
||||
if (!isRecoverableDraftDirectory || !directory) {
|
||||
return { status: "ok", directory }
|
||||
}
|
||||
|
||||
const activeProjectDirectory = resolveActiveProjectDirectory(draft)
|
||||
if (!activeProjectDirectory || normalizePath(directory) === activeProjectDirectory) {
|
||||
return { status: "ok", directory }
|
||||
}
|
||||
|
||||
const runtimeKey = getRuntimeKey()
|
||||
const draftDirectory = draft.directoryOverride
|
||||
const availability = await opencodeClient.getDirectoryAvailability(directory)
|
||||
const currentDraft = useSessionUIStore.getState().newSessionDraft
|
||||
const draftChanged = !currentDraft.open
|
||||
|| currentDraft.preserveDirectoryOverride !== draft.preserveDirectoryOverride
|
||||
|| currentDraft.pendingWorktreeRequestId !== draft.pendingWorktreeRequestId
|
||||
|| normalizePath(currentDraft.directoryOverride) !== normalizePath(draftDirectory)
|
||||
|
||||
if (getRuntimeKey() !== runtimeKey || draftChanged) {
|
||||
return { status: "aborted" }
|
||||
}
|
||||
|
||||
return {
|
||||
status: "ok",
|
||||
directory: availability === "missing" ? activeProjectDirectory : directory,
|
||||
}
|
||||
}
|
||||
|
||||
export async function materializeOpenDraftSession(selection: {
|
||||
providerID: string
|
||||
modelID: string
|
||||
@@ -1416,14 +1473,16 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
|
||||
const targetFolderId = draft.targetFolderId
|
||||
|
||||
try {
|
||||
const dir = directoryOverride ?? opencodeClient.getDirectory()
|
||||
const resolved = await resolveCreatableDraftDirectory(draft, directoryOverride)
|
||||
if (resolved.status === "aborted") return null
|
||||
const dir = resolved.directory
|
||||
const session = await createSessionAction(title, dir, parentID ?? null, metadata)
|
||||
if (!session) return null
|
||||
|
||||
get().closeNewSessionDraft()
|
||||
|
||||
if (targetFolderId) {
|
||||
const scopeKey = directoryOverride || get().lastLoadedDirectory || session.directory
|
||||
const scopeKey = dir || get().lastLoadedDirectory || session.directory
|
||||
if (scopeKey) {
|
||||
useSessionFoldersStore.getState().addSessionToFolder(scopeKey, targetFolderId, session.id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user