feat(chats): add managed projectless chat sessions
Create projectless chat sessions under a managed, date-scoped Chats directory and clean abandoned or deleted session folders. Add Chats to sidebar state, startup cache, shared context, and Electron Mini Chat while keeping VS Code project-only. Resolve managed chat directories to one server-side memory owner and document the runtime contracts.
This commit is contained in:
@@ -35,6 +35,7 @@ import { getStaleRunningToolMessageID } from "./materialization"
|
||||
import { normalizePath } from "@/lib/pathNormalization"
|
||||
import { mergeMessages } from "./optimistic"
|
||||
import { messagesBefore, messagesFrom } from "./message-ordering"
|
||||
import { deleteChatDirectory } from "@/lib/chatDirectories"
|
||||
|
||||
const MESSAGE_REFETCH_LIMIT = 100
|
||||
const SEND_CONFIRMATION_REFETCH_LIMIT = 30
|
||||
@@ -919,6 +920,15 @@ function finalizeConfirmedSessionDeletion(
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanupDeletedChatDirectory(directory: string | undefined, deleteDirectory: boolean): Promise<void> {
|
||||
if (!directory || !deleteDirectory) return
|
||||
try {
|
||||
await deleteChatDirectory(directory)
|
||||
} catch (error) {
|
||||
console.warn("[session-actions] deleted chat directory cleanup failed", error)
|
||||
}
|
||||
}
|
||||
|
||||
export type DeleteSessionOptions = {
|
||||
/**
|
||||
* Runtime key the deletion is scoped to. Defaults to the active runtime when
|
||||
@@ -947,6 +957,8 @@ export async function deleteSession(sessionId: string, options?: DeleteSessionOp
|
||||
const expectedRuntimeKey = options?.expectedRuntimeKey ?? getRuntimeKey()
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
const sessionDirectory = getSessionDirectory(sessionId)
|
||||
const sessionSnapshot = getGlobalSessionSnapshot(sessionId)
|
||||
const deleteManagedDirectory = Boolean(sessionSnapshot && sessionSnapshot.parentID == null)
|
||||
try {
|
||||
await cleanupReviewMetadataBeforeDelete(sessionId, sessionDirectory, expectedRuntimeKey)
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
@@ -956,6 +968,7 @@ export async function deleteSession(sessionId: string, options?: DeleteSessionOp
|
||||
throw new Error("session.delete failed: server did not confirm deletion")
|
||||
}
|
||||
finalizeConfirmedSessionDeletion(sessionId, sessionDirectory, expectedRuntimeKey)
|
||||
await cleanupDeletedChatDirectory(sessionDirectory, deleteManagedDirectory)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error("[session-actions] deleteSession failed", error)
|
||||
@@ -965,6 +978,7 @@ export async function deleteSession(sessionId: string, options?: DeleteSessionOp
|
||||
if ((error as { status?: number })?.status === 404) {
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
finalizeConfirmedSessionDeletion(sessionId, sessionDirectory, expectedRuntimeKey)
|
||||
await cleanupDeletedChatDirectory(sessionDirectory, deleteManagedDirectory)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -978,6 +992,8 @@ export async function deleteSessionInDirectory(
|
||||
expectedRuntimeKey = getRuntimeKey(),
|
||||
): Promise<boolean> {
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
const sessionSnapshot = getGlobalSessionSnapshot(sessionId)
|
||||
const deleteManagedDirectory = Boolean(sessionSnapshot && sessionSnapshot.parentID == null)
|
||||
try {
|
||||
await cleanupReviewMetadataBeforeDelete(sessionId, directory, expectedRuntimeKey)
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
@@ -987,12 +1003,14 @@ export async function deleteSessionInDirectory(
|
||||
throw new Error("session.delete failed: server did not confirm deletion")
|
||||
}
|
||||
finalizeConfirmedSessionDeletion(sessionId, directory, expectedRuntimeKey)
|
||||
await cleanupDeletedChatDirectory(directory, deleteManagedDirectory)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error("[session-actions] deleteSessionInDirectory failed", error)
|
||||
if ((error as { status?: number })?.status === 404) {
|
||||
if (isStaleRuntime(expectedRuntimeKey)) return false
|
||||
finalizeConfirmedSessionDeletion(sessionId, directory, expectedRuntimeKey)
|
||||
await cleanupDeletedChatDirectory(directory, deleteManagedDirectory)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user