Skip to content
Merged
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
10 changes: 7 additions & 3 deletions gateway/slash_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5958,8 +5958,11 @@ async def _handle_update_command(self, event: MessageEvent) -> str:
import textwrap
from hermes_cli._subprocess_compat import windows_detach_popen_kwargs

# hermes_cmd is a list of argv parts we can pass directly
# (no shell-quoting needed).
# Invoke the updater as a module under this interpreter rather
# than through hermes_cmd (venv\Scripts\hermes.exe): the shim
# launcher holds its own file open for the whole run, and the
# update has to replace it. Going through python.exe maps no
# shim, so the entry points can be rewritten freely.
helper = textwrap.dedent(
"""
import os, subprocess, sys
Expand All @@ -5979,7 +5982,8 @@ async def _handle_update_command(self, event: MessageEvent) -> str:
[
sys.executable, "-c", helper,
str(output_path), str(exit_code_path),
*hermes_cmd, "update", "--gateway",
sys.executable, "-m", "hermes_cli.main",
"update", "--gateway",
],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
Expand Down
15 changes: 9 additions & 6 deletions hermes_cli/_install_repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ def _resolve_install_target(root: Path) -> tuple[list[str], dict | None]:
"""
uv_bin = _er._find_uv_binary()
if uv_bin:
env = {**os.environ, "VIRTUAL_ENV": str(root / "venv")}
from hermes_constants import project_venv_dir

env = {**os.environ, "VIRTUAL_ENV": str(project_venv_dir(root) or root / "venv")}
if _is_termux_env(env):
env.pop("PYTHONPATH", None)
env.pop("PYTHONHOME", None)
Expand All @@ -102,13 +104,14 @@ def _resolve_install_target(root: Path) -> tuple[list[str], dict | None]:

def _venv_scripts_dir(root: Path) -> Path | None:
"""Project venv Scripts/bin dir, when present. stdlib-only."""
venv_dir = root / "venv"
if not venv_dir.is_dir():
return None
# hermes_constants is stdlib-only, so the canonical layout helper is safe
# hermes_constants is stdlib-only, so the canonical layout helpers are safe
# to use from this corrupted-venv repair path (#76105: never open-code
# the Scripts/bin split).
from hermes_constants import venv_bin_dir
from hermes_constants import project_venv_dir, venv_bin_dir

venv_dir = project_venv_dir(root)
if venv_dir is None:
return None

scripts = venv_bin_dir(venv_dir, windows=_is_windows())
return scripts if scripts.is_dir() else None
Expand Down
Loading
Loading