diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 39b88ea95b95..0b5edee37e92 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -1365,7 +1365,7 @@ def _read_nous_auth() -> Optional[dict]: try: if not _AUTH_JSON_PATH.is_file(): return None - data = json.loads(_AUTH_JSON_PATH.read_text()) + data = json.loads(_AUTH_JSON_PATH.read_text(encoding="utf-8")) if data.get("active_provider") != "nous": return None provider = data.get("providers", {}).get("nous", {}) diff --git a/agent/shell_hooks.py b/agent/shell_hooks.py index 3f155f20465c..88c89fe0f1bf 100644 --- a/agent/shell_hooks.py +++ b/agent/shell_hooks.py @@ -618,7 +618,7 @@ def allowlist_path() -> Path: def load_allowlist() -> Dict[str, Any]: """Return the parsed allowlist, or an empty skeleton if absent.""" try: - raw = json.loads(allowlist_path().read_text()) + raw = json.loads(allowlist_path().read_text(encoding="utf-8")) except (FileNotFoundError, json.JSONDecodeError, OSError): return {"approvals": []} if not isinstance(raw, dict): diff --git a/gateway/dead_targets.py b/gateway/dead_targets.py index 66a9247f213e..ea73c9f9e1f2 100644 --- a/gateway/dead_targets.py +++ b/gateway/dead_targets.py @@ -67,7 +67,7 @@ def __init__(self, path: Optional[Path] = None) -> None: def _load(self) -> None: try: if self._path.exists(): - raw = json.loads(self._path.read_text()) + raw = json.loads(self._path.read_text(encoding="utf-8")) if isinstance(raw, dict): # Only keep well-shaped entries. self._dead = { diff --git a/gateway/run.py b/gateway/run.py index e341292b5c6c..2a606d3e04a5 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -2978,7 +2978,7 @@ def _voice_key(self, platform: Platform, chat_id: str) -> str: def _load_voice_modes(self) -> Dict[str, str]: try: - data = json.loads(self._VOICE_MODE_PATH.read_text()) + data = json.loads(self._VOICE_MODE_PATH.read_text(encoding="utf-8")) except (FileNotFoundError, json.JSONDecodeError, OSError): return {} @@ -5513,7 +5513,7 @@ def _increment_restart_failure_counts(self, active_session_keys: set) -> None: path = _hermes_home / self._STUCK_LOOP_FILE try: - counts = json.loads(path.read_text()) if path.exists() else {} + counts = json.loads(path.read_text(encoding="utf-8")) if path.exists() else {} except Exception: counts = {} @@ -5543,7 +5543,7 @@ def _suspend_stuck_loop_sessions(self) -> int: return 0 try: - counts = json.loads(path.read_text()) + counts = json.loads(path.read_text(encoding="utf-8")) except Exception: return 0 @@ -5589,7 +5589,7 @@ def _clear_restart_failure_count(self, session_key: str) -> None: if not path.exists(): return try: - counts = json.loads(path.read_text()) + counts = json.loads(path.read_text(encoding="utf-8")) if session_key in counts: del counts[session_key] if counts: @@ -11573,7 +11573,7 @@ def _is_stale_restart_redelivery(self, event: MessageEvent) -> bool: self._booted_from_restart = False return True return False - data = json.loads(marker_path.read_text()) + data = json.loads(marker_path.read_text(encoding="utf-8")) except Exception: return False @@ -13404,7 +13404,7 @@ async def _watch_update_progress( for path in (claimed_path, pending_path): if path.exists(): try: - pending = json.loads(path.read_text()) + pending = json.loads(path.read_text(encoding="utf-8")) platform_str = pending.get("platform") chat_id = pending.get("chat_id") chat_type = pending.get("chat_type") @@ -13542,7 +13542,7 @@ async def _flush_buffer() -> None: if (prompt_path.exists() and session_key and not self._update_prompt_pending.get(session_key)): try: - prompt_data = json.loads(prompt_path.read_text()) + prompt_data = json.loads(prompt_path.read_text(encoding="utf-8")) prompt_text = prompt_data.get("prompt", "") default = prompt_data.get("default", "") if prompt_text: @@ -13636,7 +13636,7 @@ async def _send_update_notification(self) -> bool: elif not claimed_path.exists(): return True - pending = json.loads(claimed_path.read_text()) + pending = json.loads(claimed_path.read_text(encoding="utf-8")) platform_str = pending.get("platform") chat_id = pending.get("chat_id") chat_type = pending.get("chat_type") @@ -13731,7 +13731,7 @@ async def _send_restart_notification(self) -> Optional[tuple[str, str, Optional[ return None try: - data = json.loads(notify_path.read_text()) + data = json.loads(notify_path.read_text(encoding="utf-8")) platform_str = data.get("platform") chat_id = data.get("chat_id") chat_type = data.get("chat_type") diff --git a/hermes_cli/auth.py b/hermes_cli/auth.py index 7c1a0d269cf9..0721a4ba008c 100644 --- a/hermes_cli/auth.py +++ b/hermes_cli/auth.py @@ -1067,7 +1067,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: @@ -3787,7 +3787,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 @@ -4953,7 +4953,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 217eb2bb9656..62be0bdc535c 100644 --- a/hermes_cli/banner.py +++ b/hermes_cli/banner.py @@ -336,7 +336,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 diff --git a/hermes_cli/container_boot.py b/hermes_cli/container_boot.py index 327e6a5ce7f0..5a4639157231 100644 --- a/hermes_cli/container_boot.py +++ b/hermes_cli/container_boot.py @@ -370,7 +370,7 @@ def _read_desired_state(profile_dir: Path) -> str | None: if not state_file.exists(): return None try: - data = json.loads(state_file.read_text()) + data = json.loads(state_file.read_text(encoding="utf-8")) desired_state = data.get("desired_state") if desired_state is not None: return desired_state diff --git a/hermes_cli/doctor.py b/hermes_cli/doctor.py index a70fa36c90a0..a15d821d13e0 100644 --- a/hermes_cli/doctor.py +++ b/hermes_cli/doctor.py @@ -2204,7 +2204,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: diff --git a/hermes_cli/main.py b/hermes_cli/main.py index b71c59f38353..c0dbb060fa05 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -854,7 +854,7 @@ def _has_any_provider_configured() -> bool: try: import json - auth = json.loads(auth_file.read_text()) + auth = json.loads(auth_file.read_text(encoding="utf-8")) active = auth.get("active_provider") if active: status = get_auth_status(active) diff --git a/hermes_cli/service_manager.py b/hermes_cli/service_manager.py index 3cfa67309876..9ca9dbc2a2a2 100644 --- a/hermes_cli/service_manager.py +++ b/hermes_cli/service_manager.py @@ -376,7 +376,7 @@ def _write_gateway_desired_state(name: str, desired_state: str) -> None: if not profile_dir.exists(): return try: - data = json.loads(state_file.read_text()) if state_file.exists() else {} + data = json.loads(state_file.read_text(encoding="utf-8")) if state_file.exists() else {} if not isinstance(data, dict): data = {} except (OSError, json.JSONDecodeError): diff --git a/tools/managed_tool_gateway.py b/tools/managed_tool_gateway.py index d894dcb4b29b..2bbc9dcff16c 100644 --- a/tools/managed_tool_gateway.py +++ b/tools/managed_tool_gateway.py @@ -37,7 +37,7 @@ def _read_nous_provider_state() -> Optional[dict]: path = auth_json_path() if not path.is_file(): return None - data = json.loads(path.read_text()) + data = json.loads(path.read_text(encoding="utf-8")) providers = data.get("providers", {}) if not isinstance(providers, dict): return None diff --git a/tools/skills_hub.py b/tools/skills_hub.py index 0cf6a45504dd..50f2b1602598 100644 --- a/tools/skills_hub.py +++ b/tools/skills_hub.py @@ -1041,7 +1041,7 @@ def _read_cache(self, key: str) -> Optional[list]: stat = cache_file.stat() if time.time() - stat.st_mtime > INDEX_CACHE_TTL: return None - return json.loads(cache_file.read_text()) + return json.loads(cache_file.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): return None @@ -3230,7 +3230,7 @@ def _read_index_cache(key: str) -> Optional[Any]: stat = cache_file.stat() if time.time() - stat.st_mtime > INDEX_CACHE_TTL: return None - return json.loads(cache_file.read_text()) + return json.loads(cache_file.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): return None @@ -3284,7 +3284,7 @@ def load(self) -> dict: if not self.path.exists(): return {"version": 1, "installed": {}} try: - return json.loads(self.path.read_text()) + return json.loads(self.path.read_text(encoding="utf-8")) except (json.JSONDecodeError, OSError): return {"version": 1, "installed": {}} @@ -3356,7 +3356,7 @@ def load(self) -> List[dict]: if not self.path.exists(): return [] try: - data = json.loads(self.path.read_text()) + data = json.loads(self.path.read_text(encoding="utf-8")) return data.get("taps", []) except (json.JSONDecodeError, OSError): return [] @@ -3674,7 +3674,7 @@ def _load_hermes_index() -> Optional[dict]: try: age = time.time() - hermes_index_cache_file.stat().st_mtime if age < HERMES_INDEX_TTL: - return json.loads(hermes_index_cache_file.read_text()) + return json.loads(hermes_index_cache_file.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): pass @@ -3708,7 +3708,7 @@ def _load_stale_index_cache() -> Optional[dict]: hermes_index_cache_file = _hermes_index_cache_file() if hermes_index_cache_file.exists(): try: - return json.loads(hermes_index_cache_file.read_text()) + return json.loads(hermes_index_cache_file.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): pass return None diff --git a/tools/skills_sync.py b/tools/skills_sync.py index 2c0f41c47a62..094989faf296 100644 --- a/tools/skills_sync.py +++ b/tools/skills_sync.py @@ -402,7 +402,7 @@ def _backfill_optional_provenance(quiet: bool = False) -> List[str]: lock_path = SKILLS_DIR / ".hub" / "lock.json" try: - data = json.loads(lock_path.read_text()) if lock_path.exists() else {"version": 1, "installed": {}} + data = json.loads(lock_path.read_text(encoding="utf-8")) if lock_path.exists() else {"version": 1, "installed": {}} except (json.JSONDecodeError, OSError): data = {"version": 1, "installed": {}} installed = data.setdefault("installed", {}) diff --git a/tools/xai_http.py b/tools/xai_http.py index fb1f523175f0..3067804f5bee 100644 --- a/tools/xai_http.py +++ b/tools/xai_http.py @@ -41,7 +41,7 @@ def has_xai_credentials() -> bool: auth_path = get_hermes_home() / "auth.json" if not auth_path.exists(): return False - store = json.loads(auth_path.read_text()) + store = json.loads(auth_path.read_text(encoding="utf-8")) providers = store.get("providers") if isinstance(store, dict) else None xai_state = providers.get("xai-oauth") if isinstance(providers, dict) else None tokens = xai_state.get("tokens") if isinstance(xai_state, dict) else None