diff --git a/CHANGELOG.md b/CHANGELOG.md index 236e78da..a6cecadb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## [Unreleased] +### Fixed + +- **Desktop tab titles keep the active session name when profile/settings boot paths refresh the assistant name (#4086).** `applyBotName()` now leaves `document.title` alone while a chat session is active, so `syncTopbar()` remains the owner of the per-session `" — "` title and desktop tabs no longer collapse to the same fallback name. + ## [v0.51.382] — 2026-06-13 — Release MU (Stable Assistant Turn Anchors: activity-scene projection, inert, #4093) ### Added diff --git a/static/boot.js b/static/boot.js index c8e62a79..e89cea5c 100644 --- a/static/boot.js +++ b/static/boot.js @@ -1761,7 +1761,7 @@ function applyBotName(){ // The saved assistant name applies to the default profile only. // Non-default profiles use their own profile names. const name=assistantDisplayName(); - document.title=name; + if(!S.session) document.title=name; const sidebarH1=document.querySelector('.sidebar-header h1'); if(sidebarH1) sidebarH1.textContent=name; const logo=document.querySelector('.sidebar-header .logo'); diff --git a/tests/test_issue4086_document_title_owner.py b/tests/test_issue4086_document_title_owner.py new file mode 100644 index 00000000..27876eac --- /dev/null +++ b/tests/test_issue4086_document_title_owner.py @@ -0,0 +1,40 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +BOOT_JS = ROOT / "static" / "boot.js" +UI_JS = ROOT / "static" / "ui.js" + + +def _extract_function(src: str, signature: str) -> str: + start = src.find(signature) + assert start != -1, f"{signature} not found" + depth = 0 + for idx in range(start, len(src)): + ch = src[idx] + if ch == "{": + depth += 1 + elif ch == "}": + depth -= 1 + if depth == 0: + return src[start : idx + 1] + raise AssertionError(f"{signature} body did not terminate") + + +def test_apply_bot_name_does_not_overwrite_active_session_document_title(): + """Session titles belong to syncTopbar() while a chat session is active.""" + src = BOOT_JS.read_text() + body = _extract_function(src, "function applyBotName(){") + + assert "if(!S.session) document.title=name;" in body + assert "document.title=name;" not in body.replace( + "if(!S.session) document.title=name;", + "", + ) + + +def test_sync_topbar_remains_session_document_title_owner(): + src = UI_JS.read_text() + body = _extract_function(src, "function syncTopbar(){") + + assert "document.title=sessionTitle+' \\u2014 '+assistantDisplayName();" in body