Add session list refresh with server cache bypass

useSession now exposes a refreshSessions() callback that fetches
/api/sessions?refresh=1. The sessions route checks for the refresh
query parameter and resets the cache timestamp to zero, forcing a
fresh scan of ~/.claude/projects/ on the next request.

This enables users to pick up new sessions without restarting the
server or waiting for the 30-second cache to expire.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 13:35:37 -05:00
parent e5c5e470b0
commit b0b330e0ba
2 changed files with 12 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ interface SessionState {
sessionLoading: boolean; sessionLoading: boolean;
sessionError: string | null; sessionError: string | null;
loadSessions: () => Promise<void>; loadSessions: () => Promise<void>;
refreshSessions: () => Promise<void>;
loadSession: (id: string) => Promise<void>; loadSession: (id: string) => Promise<void>;
} }
@@ -21,11 +22,12 @@ export function useSession(): SessionState {
const [sessionLoading, setSessionLoading] = useState(false); const [sessionLoading, setSessionLoading] = useState(false);
const [sessionError, setSessionError] = useState<string | null>(null); const [sessionError, setSessionError] = useState<string | null>(null);
const loadSessions = useCallback(async () => { const fetchSessions = useCallback(async (refresh = false) => {
setSessionsLoading(true); setSessionsLoading(true);
setSessionsError(null); setSessionsError(null);
try { try {
const res = await fetch("/api/sessions"); const url = refresh ? "/api/sessions?refresh=1" : "/api/sessions";
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`); if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json(); const data = await res.json();
setSessions(data.sessions); setSessions(data.sessions);
@@ -38,6 +40,9 @@ export function useSession(): SessionState {
} }
}, []); }, []);
const loadSessions = useCallback(() => fetchSessions(false), [fetchSessions]);
const refreshSessions = useCallback(() => fetchSessions(true), [fetchSessions]);
const loadSession = useCallback(async (id: string) => { const loadSession = useCallback(async (id: string) => {
setSessionLoading(true); setSessionLoading(true);
setSessionError(null); setSessionError(null);
@@ -67,6 +72,7 @@ export function useSession(): SessionState {
sessionLoading, sessionLoading,
sessionError, sessionError,
loadSessions, loadSessions,
refreshSessions,
loadSession, loadSession,
}; };
} }

View File

@@ -19,8 +19,11 @@ async function getCachedSessions(): Promise<SessionEntry[]> {
return cachedSessions; return cachedSessions;
} }
sessionsRouter.get("/", async (_req, res) => { sessionsRouter.get("/", async (req, res) => {
try { try {
if (req.query.refresh === "1") {
cacheTimestamp = 0;
}
const sessions = await getCachedSessions(); const sessions = await getCachedSessions();
res.json({ sessions }); res.json({ sessions });
} catch (err) { } catch (err) {