diff --git a/src/server/routes/session.ts b/src/server/routes/session.ts index 27e11d36c..7786324c4 100644 --- a/src/server/routes/session.ts +++ b/src/server/routes/session.ts @@ -322,29 +322,30 @@ export function createSessionRoutes( .patch('/session/:sessionID', async c => { const id = c.req.param('sessionID') const handle = sessionManager.getSession(id) - if (!handle) throw notFound('session not found') const body = await c.req.json<{ title?: string model?: string permission_mode?: string + time?: { archived?: number } }>() - if (body.title) handle.setTitle(body.title) - if (body.model) await handle.setModel(body.model) - if (body.permission_mode) await handle.setPermissionMode(body.permission_mode) + if (handle) { + if (body.title) handle.setTitle(body.title) + if (body.model) await handle.setModel(body.model) + if (body.permission_mode) await handle.setPermissionMode(body.permission_mode) + } return c.json({ session_id: id, - title: handle.title ?? body.title, - model: handle.model, - permission_mode: handle.permissionMode, + title: handle?.title ?? body.title, + model: handle?.model, + permission_mode: handle?.permissionMode, }) }) .delete('/session/:sessionID', async c => { const id = c.req.param('sessionID') - const deleted = await sessionManager.deleteSession(id) - if (!deleted) throw notFound('session not found') + await sessionManager.deleteSession(id) return c.json({ deleted: true }) }) .post('/session/:sessionID/prompt', async c => { diff --git a/src/server/sessionManager.ts b/src/server/sessionManager.ts index 46248247c..60b71da3b 100644 --- a/src/server/sessionManager.ts +++ b/src/server/sessionManager.ts @@ -1,5 +1,5 @@ import { readFile, writeFile, mkdir } from 'fs/promises' -import { existsSync, statSync } from 'fs' +import { existsSync, statSync, unlinkSync } from 'fs' import { join, resolve, isAbsolute } from 'path' import { getClaudeConfigHomeDir } from '../utils/envUtils.js' import { logError } from '../utils/log.js' @@ -7,7 +7,7 @@ import type { EventBus } from './eventBus.js' import { SessionHandle } from './sessionHandle.js' import type { InitData } from './types.js' import type { SessionIndex, SessionIndexEntry, SessionBusyStatus, SessionState } from './types.js' -import { canonicalizePath } from '../utils/sessionStoragePortable.js' +import { canonicalizePath, findProjectDir, resolveSessionFilePath } from '../utils/sessionStoragePortable.js' const INDEX_FILE = 'server-sessions.json' @@ -264,16 +264,29 @@ export class SessionManager { async deleteSession(id: string): Promise { const handle = this.sessions.get(id) - if (!handle) return false - const silent = handle.silent - handle.forceKill() - this.sessions.delete(id) - this.eventBus.unregisterSessionCwd(id) - if (!silent) { - this.eventBus.publishSessionEvent(id, 'deleted', { status: 'stopped' }) + if (handle) { + const silent = handle.silent + handle.forceKill() + this.sessions.delete(id) + this.eventBus.unregisterSessionCwd(id) + if (!silent) { + this.eventBus.publishSessionEvent(id, 'deleted', { status: 'stopped' }) + } + this.scheduleIndexSave() + return true } - this.scheduleIndexSave() - return true + + // 历史 session 不在内存中,删除磁盘 transcript 文件 + try { + const resolved = await resolveSessionFilePath(id) + if (resolved) { + unlinkSync(resolved.filePath) + this.loadedIndex.delete(id) + this.scheduleIndexSave() + return true + } + } catch {} + return false } async destroyAll(): Promise {