diff --git a/app/src/main/index.ts b/app/src/main/index.ts index dbfa692..c44344a 100644 --- a/app/src/main/index.ts +++ b/app/src/main/index.ts @@ -13,6 +13,7 @@ import { acquireWriterLease, writerLockPathFor } from '../../../packages/core/sr import type { SessionPatchCursor, SessionPatchSnapshot, + SessionMetadata, SourceQueryOptions, } from '../shared/ipc-types.ts'; import type { @@ -463,10 +464,31 @@ function querySessionDisplaySnapshot(sessionId: string): SessionPatchSnapshot { }; } +const SESSION_METADATA_COLUMNS = [ + 'id', + 'title', + 'project', + 'project_path', + 'started_at', + 'ended_at', + 'git_branch', + 'version', + 'message_count', + 'jsonl_path', + 'source', +].join(', '); + +function querySessionMetadata(sessionId: string): SessionMetadata | null { + if (!db) return null; + return ( + db.prepare(`SELECT ${SESSION_METADATA_COLUMNS} FROM sessions WHERE id = ?`).get(sessionId) as SessionMetadata | undefined + ) || null; +} + ipcMain.handle('db:getSessions', (_, opts = {}) => { if (!db) return []; const { project, limit = 200 } = opts; - let sql = `SELECT id, title, project, project_path, started_at, ended_at, git_branch, version, message_count, jsonl_path, source FROM sessions`; + let sql = `SELECT ${SESSION_METADATA_COLUMNS} FROM sessions`; const params: unknown[] = []; const sourceFilter = sourceWhereClause(opts); if (sourceFilter.sql) { @@ -505,7 +527,10 @@ ipcMain.handle('db:getSessionPatch', ( cursor: SessionPatchCursor, ) => { if (!db) return null; - return createSessionPatch(querySessionDisplaySnapshot(sessionId), cursor); + return { + ...createSessionPatch(querySessionDisplaySnapshot(sessionId), cursor), + session: querySessionMetadata(sessionId), + }; }); ipcMain.handle('db:getSubagentMessages', (_, agentId) => { diff --git a/app/src/renderer/src/App.vue b/app/src/renderer/src/App.vue index a6c2d53..29e8c05 100644 --- a/app/src/renderer/src/App.vue +++ b/app/src/renderer/src/App.vue @@ -3,6 +3,7 @@ import { computed, watch, ref, provide, onMounted, onUnmounted } from 'vue'; import { useRouter, useRoute } from 'vue-router'; import { state, + getSessionSummary, FOLDER_SVG, resetListState, setView, @@ -21,6 +22,10 @@ const router = useRouter(); const route = useRoute(); let searchTimer = null; +const routeSession = computed(() => { + return getSessionSummary(route.params.id); +}); + // --- Sidebar data --- const activeCount = computed(() => state.memories.filter(m => !m.archived).length); @@ -84,7 +89,7 @@ const windowTitle = computed(() => { scopeText = 'Settings'; } else if (route.name?.startsWith('Session')) { if (route.name === 'SessionDetail' || route.name === 'SubagentDetail') { - const s = state.sessions.find(x => x.id === route.params.id); + const s = routeSession.value; scopeText = s ? `Sessions · ${s.title}` : 'Sessions'; } else { const proj = state.projectFilter !== 'all' ? ` · ${formatProjectLabel(state.projectFilter)}` : ''; @@ -470,13 +475,13 @@ provide('recapGenerateOpen', recapGenerateOpen);