Merge pull request #82345 from NousResearch/bb/home-dupe

Stop /home showing up as a second Home project in the sidebar
This commit is contained in:
brooklyn! 2026-08-09 02:38:52 -05:00 committed by GitHub
commit 934546fd5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 9 deletions

View File

@ -301,6 +301,28 @@ def test_desktop_launch_cwd_is_not_persisted_as_a_workspace():
) == "/picked/repo"
def test_home_container_dirs_are_never_a_workspace(tmp_path):
"""`/home` and `/Users` hold homes; they are not workspaces themselves.
A session whose cwd is one of them used to be promoted to its own auto
project, so the sidebar showed a second row labelled "home" sitting right
next to the synthetic Home bucket. Both POSIX spellings are excluded on
every host: either can reach a local row (macOS ships an empty `/home`
stub) or arrive from a container/remote shell.
"""
home = os.path.realpath(os.path.expanduser("~"))
for path in (os.sep, home, os.path.dirname(home), "/home", "/Users"):
assert server._is_session_cwd_junk(path), path
assert server._is_repo_junk(path), path
# An ordinary directory is still a workspace.
workspace = tmp_path / "a-repo"
workspace.mkdir()
assert not server._is_session_cwd_junk(str(workspace))
assert not server._is_repo_junk(str(workspace))
def test_disabled_discovery_clears_cache_and_rejects_new_scan(monkeypatch, tmp_path):
repo = tmp_path / "cached-repo"
repo.mkdir()

View File

@ -11510,20 +11510,41 @@ def _(rid, params, pdb, conn) -> dict:
return _ok(rid, {"project": proj.to_dict() if proj else None, "cwd": cwd, "branch": _git_branch_for_cwd(cwd)})
def _non_workspace_dirs() -> set[str]:
"""Directories that are never a workspace, whichever tier proposes them.
The filesystem root, the user's home, and the directory homes live in —
``/home`` on Linux, ``/Users`` on macOS, ``C:\\Users`` on Windows. Both
POSIX spellings are excluded on every host because both are reachable as a
cwd anywhere: macOS ships an empty ``/home`` autofs stub, and a container or
remote shell hands back Linux paths. Promoting one of these mints a
catch-all project that swallows unplaced sessions, and ``/home`` in
particular renders as a second row reading "home" next to the Home bucket.
"""
home = os.path.realpath(os.path.expanduser("~"))
candidates = (os.sep, home, os.path.dirname(home), "/home", "/Users")
return {os.path.normcase(os.path.realpath(path)) for path in candidates if path}
def _is_repo_junk(root: str) -> bool:
"""A git root we never auto-surface as a project: the bare home dir or
anything under HERMES_HOME (~/.hermes by default) config/sessions/skills,
not a workspace. User-created projects pointing there are still honored."""
"""A git root we never auto-surface as a project: a non-workspace dir (see
:func:`_non_workspace_dirs`) or anything under HERMES_HOME (~/.hermes by
default) config/sessions/skills, not a workspace. User-created projects
pointing there are still honored."""
if not root:
return True
from hermes_constants import get_hermes_home
real = os.path.realpath(root)
home = os.path.realpath(os.path.expanduser("~"))
hermes_home = os.path.realpath(str(get_hermes_home()))
return real == home or real == hermes_home or real.startswith(hermes_home + os.sep)
return (
os.path.normcase(real) in _non_workspace_dirs()
or real == hermes_home
or real.startswith(hermes_home + os.sep)
)
def _is_session_cwd_junk(cwd: str) -> bool:
@ -11531,8 +11552,9 @@ def _is_session_cwd_junk(cwd: str) -> bool:
Unlike discovered git roots, an explicitly selected descendant of
HERMES_HOME may be an intentional prose/data workspace. The pre-Projects
desktop surfaced every such cwd, so exclude only the two broad defaults
that would create catch-all projects.
desktop surfaced every such cwd, so exclude only the broad defaults that
would create catch-all projects: HERMES_HOME itself and the dirs in
:func:`_non_workspace_dirs`.
"""
if not cwd:
return True
@ -11540,9 +11562,8 @@ def _is_session_cwd_junk(cwd: str) -> bool:
from hermes_constants import get_hermes_home
real = os.path.normcase(os.path.realpath(cwd))
home = os.path.normcase(os.path.realpath(os.path.expanduser("~")))
hermes_home = os.path.normcase(os.path.realpath(str(get_hermes_home())))
return real == home or real == hermes_home
return real in _non_workspace_dirs() or real == hermes_home
def _repo_discovery_policy(raw: dict | None = None) -> dict: