Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions hermes_cli/tools_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pathlib import Path
from typing import Dict, List, Optional, Set

from tools.environments.local import _sanitize_subprocess_env

from hermes_cli.config import (
cfg_get,
Expand Down Expand Up @@ -584,7 +585,7 @@ def _pip_install(
(or the last failure for the caller to inspect).
"""
venv_root = Path(sys.executable).parent.parent
uv_env = {**os.environ, "VIRTUAL_ENV": str(venv_root)}
uv_env = _sanitize_subprocess_env(os.environ.copy(), extra_env={"VIRTUAL_ENV": str(venv_root)})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of calling _sanitize_subprocess_env(os.environ.copy()) multiple times within _pip_install, we can sanitize the environment once at the beginning of the function and reuse it. This avoids redundant environment copying and sanitization overhead across the multiple subprocess calls.

Suggested change
uv_env = _sanitize_subprocess_env(os.environ.copy(), extra_env={"VIRTUAL_ENV": str(venv_root)})
sanitized_env = _sanitize_subprocess_env(os.environ.copy())
uv_env = {**sanitized_env, "VIRTUAL_ENV": str(venv_root)}


uv_bin = shutil.which("uv")
if uv_bin:
Expand All @@ -607,6 +608,7 @@ def _pip_install(
probe = subprocess.run(
pip_cmd + ["--version"],
capture_output=True, text=True, timeout=15,
env=_sanitize_subprocess_env(os.environ.copy()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Reuse the sanitized_env defined at the beginning of the function to avoid redundant environment sanitization.

Suggested change
env=_sanitize_subprocess_env(os.environ.copy()),
env=sanitized_env,

)
if probe.returncode != 0:
raise FileNotFoundError("pip not in venv")
Expand All @@ -615,6 +617,7 @@ def _pip_install(
subprocess.run(
[sys.executable, "-m", "ensurepip", "--upgrade", "--default-pip"],
capture_output=True, text=True, timeout=120, check=True,
env=_sanitize_subprocess_env(os.environ.copy()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Reuse the sanitized_env defined at the beginning of the function to avoid redundant environment sanitization.

Suggested change
env=_sanitize_subprocess_env(os.environ.copy()),
env=sanitized_env,

)
except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
# Synthesize a result so callers see a clean failure path.
Expand All @@ -626,6 +629,7 @@ def _pip_install(
return subprocess.run(
pip_cmd + ["install", *args],
capture_output=capture_output, text=True, timeout=timeout,
env=_sanitize_subprocess_env(os.environ.copy()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Reuse the sanitized_env defined at the beginning of the function to avoid redundant environment sanitization.

Suggested change
env=_sanitize_subprocess_env(os.environ.copy()),
env=sanitized_env,

)


Expand All @@ -646,7 +650,8 @@ def _run_post_setup(post_setup_key: str):
# behaviour as before.
result = subprocess.run(
[npm_bin, "install", "--silent"],
capture_output=True, text=True, cwd=str(PROJECT_ROOT)
capture_output=True, text=True, cwd=str(PROJECT_ROOT),
env=_sanitize_subprocess_env(os.environ.copy()),
)
if result.returncode == 0:
_print_success(" Node.js dependencies installed")
Expand Down Expand Up @@ -722,6 +727,7 @@ def _run_post_setup(post_setup_key: str):
result = subprocess.run(
install_cmd,
capture_output=True, text=True, cwd=str(PROJECT_ROOT), timeout=600,
env=_sanitize_subprocess_env(os.environ.copy()),
)
if result.returncode == 0:
_print_success(" Chromium installed")
Expand Down Expand Up @@ -751,7 +757,8 @@ def _run_post_setup(post_setup_key: str):
# Absolute npm path so .cmd shim executes on Windows.
result = subprocess.run(
[_npm_bin, "install", "--silent"],
capture_output=True, text=True, cwd=str(PROJECT_ROOT)
capture_output=True, text=True, cwd=str(PROJECT_ROOT),
env=_sanitize_subprocess_env(os.environ.copy()),
)
if result.returncode == 0:
_print_success(" Camofox installed")
Expand Down Expand Up @@ -779,6 +786,7 @@ def _run_post_setup(post_setup_key: str):
version = subprocess.run(
["cua-driver", "--version"],
capture_output=True, text=True, timeout=5,
env=_sanitize_subprocess_env(os.environ.copy()),
).stdout.strip()
_print_success(f" cua-driver already installed: {version or 'unknown version'}")
except Exception:
Expand All @@ -798,7 +806,10 @@ def _run_post_setup(post_setup_key: str):
"https://raw.githubusercontent.com/trycua/cua/main/"
"libs/cua-driver/scripts/install.sh)\""
)
result = subprocess.run(install_cmd, shell=True, timeout=300)
result = subprocess.run(
install_cmd, shell=True, timeout=300,
env=_sanitize_subprocess_env(os.environ.copy()),
)
if result.returncode == 0 and shutil.which("cua-driver"):
_print_success(" cua-driver installed.")
_print_info(" IMPORTANT — grant macOS permissions now:")
Expand Down
2 changes: 1 addition & 1 deletion tests/tools/test_process_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def test_close_stdin_blocks_unapproved_pending_payload(self, registry):

def test_close_stdin_allows_eof_driven_process_to_finish(self, registry, tmp_path):
session = registry.spawn_local(
'python3 -c "import sys; print(sys.stdin.read().strip())"',
'cat',
cwd=str(tmp_path),
use_pty=False,
)
Expand Down
Loading