diff --git a/static/boot.js b/static/boot.js index b3daf912..70f50ebe 100644 --- a/static/boot.js +++ b/static/boot.js @@ -85,7 +85,7 @@ async function _savedSessionShouldStaySidebarOnly(sid){ try{ const data = await api(`/api/session?session_id=${encodeURIComponent(sid)}&messages=0&resolve_model=0`); const session = data&&data.session; - return !!(session&&(session.active_stream_id||session.pending_user_message)); + return !!(session&&(session.active_stream_id||session.pending_user_message||session.archived)); }catch(e){ return false; } diff --git a/static/sessions.js b/static/sessions.js index 4aa8e388..2a991bc1 100644 --- a/static/sessions.js +++ b/static/sessions.js @@ -3558,6 +3558,7 @@ async function _archiveSession(session, archived=true, beforeListRender=null){ const cached=(_allSessions||[]).find(s=>s&&s.session_id===session.session_id); if(cached) cached.archived=archived; if(S.session&&S.session.session_id===session.session_id) S.session.archived=archived; + try{ if(archived&&session.session_id&&localStorage.getItem('hermes-webui-session')===session.session_id) localStorage.removeItem('hermes-webui-session'); }catch(_){ } showToast(session.archived?_sessionArchiveToast(response,session):t('session_restored')); if(renderHold) await renderHold; if(_showArchived&&!_sessionPrefersReducedMotion()) _sessionSwipeReturnOffsets.set(session.session_id,'0px'); diff --git a/tests/test_1694_root_saved_running_policy.py b/tests/test_1694_root_saved_running_policy.py index e5ebb218..00a72234 100644 --- a/tests/test_1694_root_saved_running_policy.py +++ b/tests/test_1694_root_saved_running_policy.py @@ -72,6 +72,10 @@ def test_saved_running_session_helper_uses_metadata_only_and_runtime_markers(): assert "resolve_model=0" in helper, "helper must avoid unnecessary model resolution" assert "active_stream_id" in helper, "helper must treat active_stream_id as running" assert "pending_user_message" in helper, "helper must treat pending_user_message as running" + assert "session.archived" in helper, ( + "helper must skip auto-opening archived localStorage sessions so root " + "boot lands on the empty state instead of reopening archived chats" + ) assert "loadSession(" not in helper, ( "helper must not call loadSession(), because that would already project " "the saved session into the active pane" diff --git a/tests/test_session_action_menu_regression.py b/tests/test_session_action_menu_regression.py index e9fd77c1..f3fe576b 100644 --- a/tests/test_session_action_menu_regression.py +++ b/tests/test_session_action_menu_regression.py @@ -46,6 +46,19 @@ def test_archive_action_repaints_sidebar_before_full_refresh(): assert helper_body.index(api_call) < helper_body.index(optimistic) < helper_body.index(cached_render) < helper_body.index(full_refresh) +def test_archive_action_clears_saved_session_pointer_for_archived_current_session(): + """Archiving the saved active session should not leave boot localStorage stale.""" + helper_body = _function_block(SESSIONS_JS, "_archiveSession") + stale_saved_pointer_guard = ( + "try{ if(archived&&session.session_id&&localStorage.getItem('hermes-webui-session')===session.session_id) " + "localStorage.removeItem('hermes-webui-session'); }catch(_){ }" + ) + + assert stale_saved_pointer_guard in helper_body + assert helper_body.index("if(S.session&&S.session.session_id===session.session_id) S.session.archived=archived;") < helper_body.index(stale_saved_pointer_guard) + assert helper_body.index(stale_saved_pointer_guard) < helper_body.index("showToast(session.archived?_sessionArchiveToast(response,session):t('session_restored'));") + + def test_delete_action_repaints_sidebar_before_loading_remaining_sessions(): """Delete should remove the row locally before loading replacement session data.""" body = _function_block(SESSIONS_JS, "deleteSession")