From fd9032ab995c0f35eae01f5ca29d19247bf1de04 Mon Sep 17 00:00:00 2001 From: AndyMik90 Date: Wed, 18 Feb 2026 10:22:46 +0100 Subject: [PATCH] fix: resolve archive filter loss and session cache bugs in insights - Add showArchived field to insights Zustand store so all callers (including event listeners) can access it without parameter threading - loadInsightsSessions now falls back to store.showArchived when no explicit parameter is passed, fixing newSession, renameSession, updateModelConfig, and the onInsightsSessionUpdated listener - Add in-memory cache update to SessionManager.renameSession matching the pattern used by updateSessionModelConfig - Add input validation for bulk delete/archive IPC handlers Co-Authored-By: Claude Opus 4.6 --- apps/frontend/src/main/insights/session-manager.ts | 11 +++++++++++ .../src/main/ipc-handlers/insights-handlers.ts | 8 ++++++++ apps/frontend/src/renderer/components/Insights.tsx | 4 ++-- apps/frontend/src/renderer/stores/insights-store.ts | 10 +++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/main/insights/session-manager.ts b/apps/frontend/src/main/insights/session-manager.ts index 83ad5429..a6122a5c 100644 --- a/apps/frontend/src/main/insights/session-manager.ts +++ b/apps/frontend/src/main/insights/session-manager.ts @@ -190,6 +190,17 @@ export class SessionManager { session.title = newTitle; session.updatedAt = new Date(); this.storage.saveSession(projectPath, session); + + // Update cache if this session is cached + for (const [projectId, cachedSession] of this.sessions) { + if (cachedSession.id === sessionId) { + cachedSession.title = newTitle; + cachedSession.updatedAt = session.updatedAt; + this.sessions.set(projectId, cachedSession); + break; + } + } + return true; } diff --git a/apps/frontend/src/main/ipc-handlers/insights-handlers.ts b/apps/frontend/src/main/ipc-handlers/insights-handlers.ts index 32fcaca0..071fe252 100644 --- a/apps/frontend/src/main/ipc-handlers/insights-handlers.ts +++ b/apps/frontend/src/main/ipc-handlers/insights-handlers.ts @@ -264,6 +264,10 @@ export function registerInsightsHandlers(getMainWindow: () => BrowserWindow | nu ipcMain.handle( IPC_CHANNELS.INSIGHTS_DELETE_SESSIONS, async (_, projectId: string, sessionIds: string[]): Promise> => { + if (!Array.isArray(sessionIds) || sessionIds.length === 0) { + return { success: false, error: "No sessions specified" }; + } + const project = projectStore.getProject(projectId); if (!project) { return { success: false, error: "Project not found" }; @@ -299,6 +303,10 @@ export function registerInsightsHandlers(getMainWindow: () => BrowserWindow | nu ipcMain.handle( IPC_CHANNELS.INSIGHTS_ARCHIVE_SESSIONS, async (_, projectId: string, sessionIds: string[]): Promise> => { + if (!Array.isArray(sessionIds) || sessionIds.length === 0) { + return { success: false, error: "No sessions specified" }; + } + const project = projectStore.getProject(projectId); if (!project) { return { success: false, error: "Project not found" }; diff --git a/apps/frontend/src/renderer/components/Insights.tsx b/apps/frontend/src/renderer/components/Insights.tsx index ab548853..0de2b842 100644 --- a/apps/frontend/src/renderer/components/Insights.tsx +++ b/apps/frontend/src/renderer/components/Insights.tsx @@ -110,7 +110,7 @@ export function Insights({ projectId }: InsightsProps) { const [creatingTask, setCreatingTask] = useState>(new Set()); const [taskCreated, setTaskCreated] = useState>(new Set()); const [showSidebar, setShowSidebar] = useState(true); - const [showArchived, setShowArchived] = useState(false); + const showArchived = useInsightsStore((state) => state.showArchived); const [isUserAtBottom, setIsUserAtBottom] = useState(true); const [viewportEl, setViewportEl] = useState(null); @@ -272,7 +272,7 @@ export function Insights({ projectId }: InsightsProps) { }; const handleToggleShowArchived = () => { - setShowArchived(prev => !prev); + useInsightsStore.getState().setShowArchived(!showArchived); }; const handleCreateTask = async ( diff --git a/apps/frontend/src/renderer/stores/insights-store.ts b/apps/frontend/src/renderer/stores/insights-store.ts index 5f54e135..f7ad1f92 100644 --- a/apps/frontend/src/renderer/stores/insights-store.ts +++ b/apps/frontend/src/renderer/stores/insights-store.ts @@ -27,6 +27,7 @@ interface InsightsState { currentTool: ToolUsage | null; // Currently executing tool toolsUsed: InsightsToolUsage[]; // Tools used during current response isLoadingSessions: boolean; + showArchived: boolean; // Whether to include archived sessions in listings // Actions setSession: (session: InsightsSession | null) => void; @@ -44,6 +45,7 @@ interface InsightsState { finalizeStreamingMessage: () => void; clearSession: () => void; setLoadingSessions: (loading: boolean) => void; + setShowArchived: (showArchived: boolean) => void; } const initialStatus: InsightsChatStatus = { @@ -62,6 +64,7 @@ export const useInsightsStore = create((set, _get) => ({ currentTool: null, toolsUsed: [], isLoadingSessions: false, + showArchived: false, // Actions setSession: (session) => set({ session }), @@ -72,6 +75,8 @@ export const useInsightsStore = create((set, _get) => ({ setLoadingSessions: (loading) => set({ isLoadingSessions: loading }), + setShowArchived: (showArchived) => set({ showArchived }), + setPendingMessage: (message) => set({ pendingMessage: message }), addMessage: (message) => @@ -211,8 +216,11 @@ export async function loadInsightsSessions(projectId: string, includeArchived?: const store = useInsightsStore.getState(); store.setLoadingSessions(true); + // Use explicit parameter if provided, otherwise read from store + const archived = includeArchived ?? store.showArchived; + try { - const result = await window.electronAPI.listInsightsSessions(projectId, includeArchived); + const result = await window.electronAPI.listInsightsSessions(projectId, archived); if (result.success && result.data) { store.setSessions(result.data); } else {