From ad81e3c16fee91add7623f86bfe0369aca3aa139 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Sun, 26 Jul 2026 01:33:20 -0500 Subject: [PATCH] fix(gateway): only stamp a session's own directory on its row Two existing cases in tests/test_tui_gateway_server.py covered the row's cwd contract and this change had to answer both. `_persisted_session_cwd` reached through `_session_cwd`, which falls back to the gateway-wide completion cwd when the session carries none. That belongs to no session in particular, so a session that never had a directory was given one. Read the session's own `cwd` instead. The remaining case asserted that a terminal session's directory is discarded, which is the behavior this branch deliberately changes. Split it in two: a terminal session now records its workspace, and the desktop keeps the "No workspace" default it was written to protect. --- tests/test_tui_gateway_server.py | 33 ++++++++++++++++++++++++++++---- tui_gateway/server.py | 5 ++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index 4661f13040d..7b7d6b2a6d6 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -4066,9 +4066,13 @@ def test_ensure_session_db_row_persists_session_source(monkeypatch): ] -def test_ensure_session_db_row_defaults_to_no_workspace(monkeypatch, tmp_path): - """Without an explicit workspace, cwd is left null so the session groups - under "No workspace" rather than the gateway's launch directory.""" +def test_ensure_session_db_row_records_a_terminal_workspace(monkeypatch, tmp_path): + """A terminal session's directory IS its workspace, so the row records it. + + The user cd'd there before running hermes. Leaving it null stranded the row + with no cwd and no git_repo_root, so the sidebar could never place the + session under its project. + """ created = [] class _FakeDB: @@ -4085,7 +4089,28 @@ def test_ensure_session_db_row_defaults_to_no_workspace(monkeypatch, tmp_path): server._ensure_session_db_row({"session_key": "k1", "cwd": str(tmp_path)}) assert created == [ - {"key": "k1", "source": "tui", "model": "test-model", "model_config": None, "cwd": None} + {"key": "k1", "source": "tui", "model": "test-model", "model_config": None, "cwd": str(tmp_path)} + ] + + +def test_ensure_session_db_row_defaults_desktop_to_no_workspace(monkeypatch, tmp_path): + """The desktop launches from wherever the bundle was opened, so an unpicked + cwd is an artifact — those chats stay null and group under "No workspace".""" + created = [] + + class _FakeDB: + def create_session(self, key, source=None, model=None, model_config=None, parent_session_id=None, cwd=None, profile_name=None): + created.append( + {"key": key, "source": source, "model": model, "model_config": model_config, "cwd": cwd} + ) + + monkeypatch.setattr(server, "_get_db", lambda: _FakeDB()) + monkeypatch.setattr(server, "_resolve_model", lambda: "test-model") + + server._ensure_session_db_row({"session_key": "k1", "source": "desktop", "cwd": str(tmp_path)}) + + assert created == [ + {"key": "k1", "source": "desktop", "model": "test-model", "model_config": None, "cwd": None} ] diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 6cffc43e48e..9db57df8dd9 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -2102,7 +2102,10 @@ def _persisted_session_cwd(session: dict) -> str | None: return _session_cwd(session) if _session_source(session) in _LAUNCH_CWD_NOT_A_WORKSPACE: return None - return _session_cwd(session) or None + # Only the session's OWN directory. `_session_cwd` falls back to the + # gateway-wide completion cwd, which belongs to no session in particular — + # stamping that would invent a workspace for a session that never had one. + return str(session.get("cwd") or "") or None def _heal_dead_cwd(cwd: str) -> str: