diff --git a/hermes_cli/auth.py b/hermes_cli/auth.py index 4271ec204171..d07afc0cb47d 100644 --- a/hermes_cli/auth.py +++ b/hermes_cli/auth.py @@ -1041,7 +1041,7 @@ def _load_auth_store(auth_file: Optional[Path] = None) -> Dict[str, Any]: return {"version": AUTH_STORE_VERSION, "providers": {}} try: - raw = json.loads(auth_file.read_text()) + raw = json.loads(auth_file.read_text(encoding="utf-8")) except Exception as exc: corrupt_path = auth_file.with_suffix(".json.corrupt") try: @@ -3657,7 +3657,7 @@ def _import_codex_cli_tokens() -> Optional[Dict[str, str]]: if not auth_path.is_file(): return None try: - payload = json.loads(auth_path.read_text()) + payload = json.loads(auth_path.read_text(encoding="utf-8")) tokens = payload.get("tokens") if not isinstance(tokens, dict): return None @@ -4823,7 +4823,7 @@ def _read_shared_nous_state() -> Optional[Dict[str, Any]]: if not path.is_file(): return None try: - payload = json.loads(path.read_text()) + payload = json.loads(path.read_text(encoding="utf-8")) except (OSError, ValueError) as exc: logger.debug("Shared Nous auth store at %s is unreadable: %s", path, exc) return None diff --git a/hermes_cli/banner.py b/hermes_cli/banner.py index 68d33e43fdb8..a5289e1196c6 100644 --- a/hermes_cli/banner.py +++ b/hermes_cli/banner.py @@ -333,7 +333,7 @@ def check_for_updates() -> Optional[int]: now = time.time() try: if cache_file.exists(): - cached = json.loads(cache_file.read_text()) + cached = json.loads(cache_file.read_text(encoding="utf-8")) if ( now - cached.get("ts", 0) < _UPDATE_CHECK_CACHE_SECONDS and cached.get("rev") == embedded_rev @@ -359,7 +359,7 @@ def check_for_updates() -> Optional[int]: try: cache_file.write_text( - json.dumps({"ts": now, "behind": behind, "rev": embedded_rev, "ver": VERSION}) + json.dumps({"ts": now, "behind": behind, "rev": embedded_rev, "ver": VERSION}, encoding="utf-8") ) except Exception: pass diff --git a/hermes_cli/doctor.py b/hermes_cli/doctor.py index 7aadc58f5f25..3f100fb264b7 100644 --- a/hermes_cli/doctor.py +++ b/hermes_cli/doctor.py @@ -669,7 +669,7 @@ def run_doctor(args): check_ok(f"{_DHH}/.env file exists") # Check for common issues. Pin encoding to UTF-8 because .env files are - # written as UTF-8 everywhere in the codebase, while Path.read_text() + # written as UTF-8 everywhere in the codebase, while Path.read_text(encoding="utf-8") # defaults to the system locale — which crashes on non-UTF-8 Windows # locales (e.g. GBK) as soon as the file contains any non-ASCII byte. content = env_path.read_text(encoding="utf-8") @@ -2126,7 +2126,7 @@ def _probe_azure_entra() -> _ConnectivityResult: if lock_file.exists(): try: import json - lock_data = json.loads(lock_file.read_text()) + lock_data = json.loads(lock_file.read_text(encoding="utf-8")) count = len(lock_data.get("installed", {})) check_ok(f"Lock file OK ({count} hub-installed skill(s))") except Exception: @@ -2292,7 +2292,7 @@ def _gh_authenticated() -> bool: if not wrapper.is_file(): continue try: - content = wrapper.read_text() + content = wrapper.read_text(encoding="utf-8") if "hermes -p" in content: _m = _re.search(r"hermes -p (\S+)", content) if _m and not profile_exists(_m.group(1)): diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index 03435eac0281..1f5087f908f3 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -3598,7 +3598,7 @@ def launchd_install(force: bool = False): if _refuse_temp_home_service_write(new_plist, "launchd plist"): return print(f"Installing launchd service to: {plist_path}") - plist_path.write_text(new_plist) + plist_path.write_text(new_plist, encoding="utf-8") try: subprocess.run(