fix(windows): prefer managed node for whatsapp and desktop
This commit is contained in:
parent
38f1a923af
commit
7a7b56d498
5 changed files with 173 additions and 31 deletions
|
|
@ -2363,6 +2363,7 @@ def cmd_whatsapp(args):
|
|||
"""Set up WhatsApp: choose mode, configure, install bridge, pair via QR."""
|
||||
_require_tty("whatsapp")
|
||||
from hermes_cli.config import get_env_value, save_env_value
|
||||
from hermes_constants import find_node_executable, with_hermes_node_path
|
||||
|
||||
print()
|
||||
print("⚕ WhatsApp Setup")
|
||||
|
|
@ -2477,7 +2478,7 @@ def cmd_whatsapp(args):
|
|||
print(
|
||||
"\n→ Installing WhatsApp bridge dependencies (this can take a few minutes)..."
|
||||
)
|
||||
npm = shutil.which("npm")
|
||||
npm = find_node_executable("npm")
|
||||
if not npm:
|
||||
print(" ✗ npm not found on PATH — install Node.js first")
|
||||
return
|
||||
|
|
@ -2490,6 +2491,7 @@ def cmd_whatsapp(args):
|
|||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
env=with_hermes_node_path(),
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print("\n ✗ Install cancelled")
|
||||
|
|
@ -2546,8 +2548,15 @@ def cmd_whatsapp(args):
|
|||
|
||||
try:
|
||||
subprocess.run(
|
||||
["node", str(bridge_script), "--pair-only", "--session", str(session_dir)],
|
||||
[
|
||||
find_node_executable("node") or "node",
|
||||
str(bridge_script),
|
||||
"--pair-only",
|
||||
"--session",
|
||||
str(session_dir),
|
||||
],
|
||||
cwd=str(bridge_dir),
|
||||
env=with_hermes_node_path(),
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
|
@ -4535,6 +4544,7 @@ def _run_with_idle_timeout(
|
|||
*,
|
||||
idle_timeout_seconds: int = 180,
|
||||
indent: str = " ",
|
||||
env: dict[str, str] | None = None,
|
||||
) -> subprocess.CompletedProcess:
|
||||
"""Run a subprocess that streams output, with an idle-output timeout.
|
||||
|
||||
|
|
@ -4569,6 +4579,7 @@ def _run_with_idle_timeout(
|
|||
encoding="utf-8",
|
||||
errors="replace",
|
||||
bufsize=1,
|
||||
env=env,
|
||||
)
|
||||
except OSError as exc:
|
||||
# E.g. npm not on PATH between the which() check and now.
|
||||
|
|
@ -4760,12 +4771,15 @@ def _build_web_ui(web_dir: Path, *, fatal: bool = False) -> bool:
|
|||
encoding = getattr(sys.stdout, "encoding", None) or "ascii"
|
||||
print(text.encode(encoding, errors="replace").decode(encoding, errors="replace"))
|
||||
|
||||
npm = shutil.which("npm")
|
||||
from hermes_constants import find_node_executable, with_hermes_node_path
|
||||
|
||||
npm = find_node_executable("npm")
|
||||
if not npm:
|
||||
if fatal:
|
||||
_say("Web UI frontend not built and npm is not available.")
|
||||
_say("Install Node.js, then run: cd web && npm install && npm run build")
|
||||
return not fatal
|
||||
build_env = with_hermes_node_path()
|
||||
_say("→ Building web UI...")
|
||||
|
||||
def _relay(result: "subprocess.CompletedProcess") -> None:
|
||||
|
|
@ -4797,6 +4811,7 @@ def _build_web_ui(web_dir: Path, *, fatal: bool = False) -> bool:
|
|||
npm,
|
||||
npm_cwd,
|
||||
extra_args=(*npm_workspace_args, "--silent"),
|
||||
env=build_env,
|
||||
)
|
||||
if r1.returncode != 0:
|
||||
_say(
|
||||
|
|
@ -4812,13 +4827,13 @@ def _build_web_ui(web_dir: Path, *, fatal: bool = False) -> bool:
|
|||
# users react by rebooting, which leaves the editable install in a
|
||||
# half-state. Streaming + idle-kill makes failures observable AND
|
||||
# recoverable (the stale-dist fallback below handles the kill path).
|
||||
r2 = _run_with_idle_timeout([npm, "run", "build"], cwd=web_dir)
|
||||
r2 = _run_with_idle_timeout([npm, "run", "build"], cwd=web_dir, env=build_env)
|
||||
if r2.returncode != 0:
|
||||
# Retry once after a short delay — covers boot-time races on Windows
|
||||
# (antivirus scanning Node.js binaries, npm cache not ready, transient
|
||||
# I/O when launched via Scheduled Task at logon). See issue #23817.
|
||||
_time.sleep(3)
|
||||
r2 = _run_with_idle_timeout([npm, "run", "build"], cwd=web_dir)
|
||||
r2 = _run_with_idle_timeout([npm, "run", "build"], cwd=web_dir, env=build_env)
|
||||
|
||||
if r2.returncode != 0:
|
||||
# _run_with_idle_timeout merges stderr into stdout; older callers
|
||||
|
|
@ -5197,7 +5212,9 @@ def _redownload_electron_dist(
|
|||
installer = electron_dir / "install.js"
|
||||
if not installer.is_file():
|
||||
return False
|
||||
node = shutil.which("node")
|
||||
from hermes_constants import find_node_executable, with_hermes_node_path
|
||||
|
||||
node = find_node_executable("node")
|
||||
if not node:
|
||||
return False
|
||||
|
||||
|
|
@ -5208,7 +5225,7 @@ def _redownload_electron_dist(
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
dl_env = dict(env)
|
||||
dl_env = with_hermes_node_path(env)
|
||||
if mirror:
|
||||
dl_env["ELECTRON_MIRROR"] = mirror
|
||||
try:
|
||||
|
|
@ -5388,7 +5405,9 @@ def cmd_gui(args: argparse.Namespace):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
env = os.environ.copy()
|
||||
from hermes_constants import find_node_executable, with_hermes_node_path
|
||||
|
||||
env = with_hermes_node_path(os.environ.copy())
|
||||
if getattr(args, "fake_boot", False):
|
||||
env["HERMES_DESKTOP_BOOT_FAKE"] = "1"
|
||||
if getattr(args, "ignore_existing", False):
|
||||
|
|
@ -5405,7 +5424,7 @@ def cmd_gui(args: argparse.Namespace):
|
|||
packaged_executable = _desktop_packaged_executable(desktop_dir)
|
||||
|
||||
if source_mode or not skip_build:
|
||||
npm = shutil.which("npm")
|
||||
npm = find_node_executable("npm")
|
||||
if not npm:
|
||||
print("Desktop GUI requires Node.js/npm, but npm was not found on PATH.")
|
||||
print("Install Node.js, then run: hermes gui")
|
||||
|
|
@ -7637,7 +7656,9 @@ def _ensure_uv_for_termux(pip_cmd: list[str]) -> str | None:
|
|||
|
||||
|
||||
def _update_node_dependencies() -> None:
|
||||
npm = shutil.which("npm")
|
||||
from hermes_constants import find_node_executable, with_hermes_node_path
|
||||
|
||||
npm = find_node_executable("npm")
|
||||
if not npm:
|
||||
return
|
||||
|
||||
|
|
@ -7654,7 +7675,7 @@ def _update_node_dependencies() -> None:
|
|||
print("→ Updating Node.js dependencies...")
|
||||
extra_args = ["--no-fund", "--no-audit", "--progress=false"]
|
||||
|
||||
nixos_env = _nixos_build_env()
|
||||
nixos_env = with_hermes_node_path(_nixos_build_env())
|
||||
|
||||
# Step 1: root install (no workspace recursion).
|
||||
root_args = [*extra_args, "--workspaces=false"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue