From 89aef910c7bc17f2aebf09a7d850997f52ca72bc Mon Sep 17 00:00:00 2001 From: RAIT-09 <51452399+RAIT-09@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:19:41 +0900 Subject: [PATCH] feat(session-history): Add delete button and show sessions for all agents - Add deleteSession method to useSessionHistory hook - Add Delete button to all session items (always visible) - Change early return for restoration non-supporting agents to warning banner - Show locally saved sessions for all agents (for deletion) - Add warning banner and delete button styles --- src/components/chat/ChatView.tsx | 20 ++++++++ src/components/chat/SessionHistoryContent.tsx | 51 ++++++++++++------- src/hooks/useSessionHistory.ts | 49 +++++++++++++++++- styles.css | 24 +++++++++ 4 files changed, 125 insertions(+), 19 deletions(-) diff --git a/src/components/chat/ChatView.tsx b/src/components/chat/ChatView.tsx index 6aed5bb..2dc938d 100644 --- a/src/components/chat/ChatView.tsx +++ b/src/components/chat/ChatView.tsx @@ -381,6 +381,16 @@ function ChatComponent({ logger.error("Session fork error:", error); } }, + onDeleteSession: async (sessionId: string) => { + try { + logger.log(`[ChatView] Deleting session: ${sessionId}`); + await sessionHistory.deleteSession(sessionId); + new Notice("[Agent Client] Session deleted"); + } catch (error) { + new Notice("[Agent Client] Failed to delete session"); + logger.error("Session delete error:", error); + } + }, onLoadMore: () => { void sessionHistory.loadMoreSessions(); }, @@ -452,6 +462,16 @@ function ChatComponent({ logger.error("Session fork error:", error); } }, + onDeleteSession: async (sessionId: string) => { + try { + logger.log(`[ChatView] Deleting session: ${sessionId}`); + await sessionHistory.deleteSession(sessionId); + new Notice("[Agent Client] Session deleted"); + } catch (error) { + new Notice("[Agent Client] Failed to delete session"); + logger.error("Session delete error:", error); + } + }, onLoadMore: () => { void sessionHistory.loadMoreSessions(); }, diff --git a/src/components/chat/SessionHistoryContent.tsx b/src/components/chat/SessionHistoryContent.tsx index cd903f7..ccd0a46 100644 --- a/src/components/chat/SessionHistoryContent.tsx +++ b/src/components/chat/SessionHistoryContent.tsx @@ -43,6 +43,8 @@ export interface SessionHistoryContentProps { onResumeSession: (sessionId: string, cwd: string) => Promise; /** Callback when a session is forked (create new branch) */ onForkSession: (sessionId: string, cwd: string) => Promise; + /** Callback when a session is deleted */ + onDeleteSession: (sessionId: string) => Promise; /** Callback to load more sessions (pagination) */ onLoadMore: () => void; /** Callback to fetch sessions with filter */ @@ -229,6 +231,7 @@ function SessionItem({ onLoadSession, onResumeSession, onForkSession, + onDeleteSession, onClose, }: { session: SessionInfo; @@ -238,6 +241,7 @@ function SessionItem({ onLoadSession: (sessionId: string, cwd: string) => Promise; onResumeSession: (sessionId: string, cwd: string) => Promise; onForkSession: (sessionId: string, cwd: string) => Promise; + onDeleteSession: (sessionId: string) => Promise; onClose: () => void; }) { const handleLoad = useCallback(() => { @@ -255,6 +259,10 @@ function SessionItem({ void onForkSession(session.sessionId, session.cwd); }, [session, onForkSession, onClose]); + const handleDelete = useCallback(() => { + void onDeleteSession(session.sessionId); + }, [session.sessionId, onDeleteSession]); + return (
@@ -297,6 +305,12 @@ function SessionItem({ onClick={handleFork} /> )} +
); @@ -328,6 +342,7 @@ export function SessionHistoryContent({ onLoadSession, onResumeSession, onForkSession, + onDeleteSession, onLoadMore, onFetchSessions, onClose, @@ -361,18 +376,11 @@ export function SessionHistoryContent({ // Check if any session operation is available const canPerformAnyOperation = canLoad || canResume || canFork; - // Show message if no session operations are supported - if (!canPerformAnyOperation && !debugMode) { - return ( -
-

- This agent does not support session restoration. -

-
- ); - } - - const canShowList = canList || isUsingLocalSessions; + // Show local sessions list (always show for delete functionality) + // - If agent supports list: use agent's session/list + // - If agent doesn't support list OR doesn't support restoration: use locally saved sessions + const canShowList = + canList || isUsingLocalSessions || !canPerformAnyOperation; return ( <> @@ -387,13 +395,21 @@ export function SessionHistoryContent({ /> )} + {/* Warning banner for agents that don't support restoration */} + {!canPerformAnyOperation && ( +
+

+ This agent does not support session restoration. + Messages are saved locally but cannot be restored to the + agent. +

+
+ )} + {/* Local sessions banner */} - {isUsingLocalSessions && ( + {(isUsingLocalSessions || !canPerformAnyOperation) && (
- - Locally saved sessions (agent doesn't support - session/list) - + Locally saved sessions
)} @@ -470,6 +486,7 @@ export function SessionHistoryContent({ onLoadSession={onLoadSession} onResumeSession={onResumeSession} onForkSession={onForkSession} + onDeleteSession={onDeleteSession} onClose={onClose} /> ))} diff --git a/src/hooks/useSessionHistory.ts b/src/hooks/useSessionHistory.ts index 532f179..6961661 100644 --- a/src/hooks/useSessionHistory.ts +++ b/src/hooks/useSessionHistory.ts @@ -132,6 +132,12 @@ export interface UseSessionHistoryReturn { */ forkSession: (sessionId: string, cwd: string) => Promise; + /** + * Delete a session (local metadata + message file). + * @param sessionId - Session to delete + */ + deleteSession: (sessionId: string) => Promise; + /** * Invalidate the session cache. * Call this when creating a new session to refresh the list. @@ -220,15 +226,25 @@ export function useSessionHistory( cacheRef.current = null; }, []); + // Check if any restoration operation is available + const canPerformAnyOperation = + capabilities.canLoad || capabilities.canResume || capabilities.canFork; + /** * Fetch sessions list from agent or local storage. * Uses agent's session/list if supported, otherwise falls back to local storage. + * For agents that don't support restoration, local sessions are used for deletion. * Replaces existing sessions in state. */ const fetchSessions = useCallback( async (cwd?: string) => { - // If agent doesn't support list, use local sessions - if (!capabilities.canList) { + // Use local sessions if: + // - Agent doesn't support session/list, OR + // - Agent doesn't support any restoration operation (for delete only) + const shouldUseLocalSessions = + !capabilities.canList || !canPerformAnyOperation; + + if (shouldUseLocalSessions) { // Get locally saved sessions for this agent const localSessions = settingsAccess.getSavedSessions( session.agentId, @@ -289,6 +305,7 @@ export function useSessionHistory( [ agentClient, capabilities.canList, + canPerformAnyOperation, isCacheValid, settingsAccess, session.agentId, @@ -450,6 +467,33 @@ export function useSessionHistory( ], ); + /** + * Delete a session (local metadata + message file). + * Removes from both local state and persistent storage. + */ + const deleteSession = useCallback( + async (sessionId: string) => { + try { + // Delete from persistent storage (metadata + message file) + await settingsAccess.deleteSession(sessionId); + + // Remove from local state + setSessions((prev) => + prev.filter((s) => s.sessionId !== sessionId), + ); + + // Invalidate cache to ensure consistency + invalidateCache(); + } catch (err) { + const errorMessage = + err instanceof Error ? err.message : String(err); + setError(`Failed to delete session: ${errorMessage}`); + throw err; // Re-throw to allow caller to handle + } + }, + [settingsAccess, invalidateCache], + ); + return { sessions, loading, @@ -475,6 +519,7 @@ export function useSessionHistory( loadSession, resumeSession, forkSession, + deleteSession, invalidateCache, }; } diff --git a/styles.css b/styles.css index 2bc3dcf..f0c5064 100644 --- a/styles.css +++ b/styles.css @@ -1519,3 +1519,27 @@ If your plugin does not need CSS, delete this file. color: var(--text-muted); border-left: 3px solid var(--interactive-accent); } + +/* Warning banner for agents that don't support restoration */ +.agent-client-session-history-warning-banner { + padding: 8px 12px; + margin-bottom: 12px; + background: var(--background-secondary); + border-radius: 4px; + border-left: 3px solid var(--text-warning); +} + +.agent-client-session-history-warning-banner p { + margin: 0; + color: var(--text-muted); + font-size: 12px; +} + +/* Delete button */ +.agent-client-session-history-delete-icon { + color: var(--text-muted); +} + +.agent-client-session-history-delete-icon:hover { + color: var(--text-error); +}