From 62b4ebb7db4e18fd3628ada0a1a30609ed6a109e Mon Sep 17 00:00:00 2001 From: emozilla Date: Fri, 8 May 2026 13:28:06 -0400 Subject: [PATCH] auth: use get_default_hermes_root() for shared nous_auth.json path Replace hardcoded ~/.hermes/shared/ references with get_default_hermes_root() / 'shared' so the cross-profile Nous auth store lands in the correct location on every platform: - Linux/macOS: ~/.hermes/shared/ - native Windows: %LOCALAPPDATA%\hermes\shared- Docker / custom HERMES_HOME: /shared/ Updates _nous_shared_auth_dir(), the pytest seat-belt in _nous_shared_store_path(), and the auth_add_command comment to match. Previously Windows installs wrote to ~/.hermes/shared/ even though the rest of the CLI uses %LOCALAPPDATA%\hermes, so profiles couldn't see each other's shared credential. --- hermes_cli/auth.py | 25 ++++++++++++++++++------- hermes_cli/auth_commands.py | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/hermes_cli/auth.py b/hermes_cli/auth.py index 425ffb6f25..dd4b2f4f38 100644 --- a/hermes_cli/auth.py +++ b/hermes_cli/auth.py @@ -2827,9 +2827,12 @@ def _poll_for_token( # import instead of running the full device-code flow every time. # # File lives at ${HERMES_SHARED_AUTH_DIR}/nous_auth.json, defaulting to -# ~/.hermes/shared/nous_auth.json. It is OUTSIDE any named profile's -# HERMES_HOME so named profiles (which typically live under -# ~/.hermes/profiles//) all see the same file. +# ``/shared/nous_auth.json`` where ```` is what +# ``get_default_hermes_root()`` returns — ``~/.hermes`` on Linux/macOS, +# ``%LOCALAPPDATA%\hermes`` on native Windows, or the Docker/custom root. +# It is OUTSIDE any named profile's HERMES_HOME so named profiles (which +# typically live under ``/profiles//``) all see the +# same file. # # Written on successful login and on every runtime refresh so the stored # refresh_token stays current even if one profile refreshes and rotates it. @@ -2846,25 +2849,33 @@ def _nous_shared_auth_dir() -> Path: Honors ``HERMES_SHARED_AUTH_DIR`` so tests can redirect it to a tmp path without touching the real user's home. Defaults to - ``~/.hermes/shared/``. + ``/shared/``, where ```` is what + :func:`hermes_constants.get_default_hermes_root` returns — so + Linux/macOS classic installs land at ``~/.hermes/shared/``, native + Windows installs at ``%LOCALAPPDATA%\\hermes\\shared\\``, and + Docker / custom ``HERMES_HOME`` deployments at + ``/shared/``. Sits outside any named profile so all + profiles under the same root share the store. """ override = os.getenv("HERMES_SHARED_AUTH_DIR", "").strip() if override: return Path(override).expanduser() - return Path.home() / ".hermes" / "shared" + from hermes_constants import get_default_hermes_root + return get_default_hermes_root() / "shared" def _nous_shared_store_path() -> Path: path = _nous_shared_auth_dir() / NOUS_SHARED_STORE_FILENAME # Seat belt: if pytest is running and this resolves to a path under the - # real user's home, refuse rather than silently corrupt cross-profile + # real user's Hermes root, refuse rather than silently corrupt cross-profile # state. Tests must set HERMES_SHARED_AUTH_DIR to a tmp_path (conftest # does not do this automatically — mirror the _auth_file_path() guard # so forgetting to set it fails loudly instead of writing to the real # shared store). if os.environ.get("PYTEST_CURRENT_TEST"): + from hermes_constants import get_default_hermes_root real_home_shared = ( - Path.home() / ".hermes" / "shared" / NOUS_SHARED_STORE_FILENAME + get_default_hermes_root() / "shared" / NOUS_SHARED_STORE_FILENAME ).resolve(strict=False) try: resolved = path.resolve(strict=False) diff --git a/hermes_cli/auth_commands.py b/hermes_cli/auth_commands.py index a29776aea2..4312f688a3 100644 --- a/hermes_cli/auth_commands.py +++ b/hermes_cli/auth_commands.py @@ -246,7 +246,7 @@ def auth_add_command(args) -> None: if provider == "nous": # Codex-style auto-import: if a shared Nous credential lives at - # ~/.hermes/shared/nous_auth.json (written by any previous + # /shared/nous_auth.json (written by any previous # successful login), offer to import it instead of running the # full device-code flow. This makes `hermes --profile # auth add nous --type oauth` a one-tap operation for users who