From 646b4ec5338072a20c11bdaf7dc4f9c1f6d3d557 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Fri, 13 Mar 2026 07:54:46 -0700 Subject: [PATCH] fix(terminal): strip provider env vars from background and PTY subprocesses (#1172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Home Assistant event filtering now closed by default Previously, when no watch_domains or watch_entities were configured, ALL state_changed events passed through to the agent, causing users to be flooded with notifications for every HA entity change. Now events are dropped by default unless the user explicitly configures: - watch_domains: list of domains to monitor (e.g. climate, light) - watch_entities: list of specific entity IDs to monitor - watch_all: true (new option — opt-in to receive all events) A warning is logged at connect time if no filters are configured, guiding users to set up their HA platform config. All 49 gateway HA tests + 52 HA tool tests pass. * docs: update Home Assistant integration documentation - homeassistant.md: Fix event filtering docs to reflect closed-by-default behavior. Add watch_all option. Replace Python dict config example with YAML. Fix defaults table (was incorrectly showing 'all'). Add required configuration warning admonition. - environment-variables.md: Add HASS_TOKEN and HASS_URL to Messaging section. - messaging/index.md: Add Home Assistant to description, architecture diagram, platform toolsets table, and Next Steps links. * fix(terminal): strip provider env vars from background and PTY subprocesses Extends the env var blocklist from #1157 to also cover the two remaining leaky paths in process_registry.py: - spawn_local() PTY path (line 156) - spawn_local() background Popen path (line 197) Both were still using raw os.environ, leaking provider vars to background processes and interactive PTY sessions. Now uses the same dynamic _HERMES_PROVIDER_ENV_BLOCKLIST from local.py. Explicit env_vars passed to spawn_local() still override the blocklist, matching the existing behavior for callers that intentionally need these. Gap identified by PR #1004 (@PeterFile). --- tools/process_registry.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/process_registry.py b/tools/process_registry.py index 10d8c291..2c044f9f 100644 --- a/tools/process_registry.py +++ b/tools/process_registry.py @@ -42,7 +42,7 @@ import time import uuid _IS_WINDOWS = platform.system() == "Windows" -from tools.environments.local import _find_shell +from tools.environments.local import _find_shell, _HERMES_PROVIDER_ENV_BLOCKLIST from dataclasses import dataclass, field from pathlib import Path from typing import Any, Dict, List, Optional @@ -153,7 +153,9 @@ class ProcessRegistry: else: from ptyprocess import PtyProcess as _PtyProcessCls user_shell = _find_shell() - pty_env = os.environ | (env_vars or {}) + pty_env = {k: v for k, v in os.environ.items() + if k not in _HERMES_PROVIDER_ENV_BLOCKLIST} + pty_env.update(env_vars or {}) pty_env["PYTHONUNBUFFERED"] = "1" pty_proc = _PtyProcessCls.spawn( [user_shell, "-lic", command], @@ -194,7 +196,9 @@ class ProcessRegistry: # Force unbuffered output for Python scripts so progress is visible # during background execution (libraries like tqdm/datasets buffer when # stdout is a pipe, hiding output from process(action="poll")). - bg_env = os.environ | (env_vars or {}) + bg_env = {k: v for k, v in os.environ.items() + if k not in _HERMES_PROVIDER_ENV_BLOCKLIST} + bg_env.update(env_vars or {}) bg_env["PYTHONUNBUFFERED"] = "1" proc = subprocess.Popen( [user_shell, "-lic", command],