Merge branch 'main' into bb/gui

Conflicts resolved:
- package.json / package-lock.json: drop @askjo/camofox-browser from
  root deps per main's lazy-install change (#27055); keep bb/gui's
  workspaces=["apps/*"] and @streamdown/math; regenerated lockfile.
- hermes_cli/main.py (_update_node_dependencies): combine main's
  streaming-output change (drop --silent, capture_output=False so
  postinstall progress is visible — #18840) with bb/gui's
  --workspaces=false guard so npm does not recurse into apps/*
  workspaces (those install/build on demand via _build_web_ui).
- hermes_cli/main.py (_BUILTIN_SUBCOMMANDS): add main's new
  'send' subcommand so plugin-discovery fast-path skips it.
- tests/hermes_cli/test_cmd_update.py: align with combined flag set
  (repo gets --workspaces=false, ui-tui does not, dashboard install
  + build still 3rd) and retain main's capture_output=False
  regression assertion for repo + ui-tui installs.
This commit is contained in:
Brooklyn Nicholson
2026-05-16 21:55:54 -05:00
13 changed files with 2650 additions and 3 deletions
+22 -3
View File
@@ -7256,7 +7256,18 @@ def _update_node_dependencies() -> None:
if not (path / "package.json").exists():
continue
extra_args = ["--silent", "--no-fund", "--no-audit", "--progress=false"]
# Stream npm output (no `--silent`, no `capture_output`) so any
# optional dependency postinstall scripts (e.g. `agent-browser`'s
# Chromium fetch on first install) print progress instead of
# appearing to hang silently for minutes (#18840). The
# `_UpdateOutputStream` wrapper installed by the updater mirrors
# streamed output to ``~/.hermes/logs/update.log`` so nothing is lost.
#
# The repo root install also passes `--workspaces=false` so npm
# does not recursively install every `apps/*` workspace (dashboard,
# desktop, shared) — those are installed/built on demand via
# `_build_web_ui()` and the desktop launchers.
extra_args = ["--no-fund", "--no-audit", "--progress=false"]
if path == PROJECT_ROOT:
extra_args.append("--workspaces=false")
@@ -7264,13 +7275,14 @@ def _update_node_dependencies() -> None:
npm,
path,
extra_args=tuple(extra_args),
capture_output=False,
)
if result.returncode == 0:
print(f"{label}")
continue
print(f" ⚠ npm install failed in {label}")
stderr = (result.stderr or "").strip()
stderr = (result.stderr or "").strip() if result.stderr else ""
if stderr:
print(f" {stderr.splitlines()[-1]}")
@@ -9652,7 +9664,8 @@ _BUILTIN_SUBCOMMANDS = frozenset(
"config", "cron", "curator", "dashboard", "debug", "doctor",
"dump", "fallback", "gateway", "hooks", "import", "insights",
"kanban", "login", "logout", "logs", "lsp", "mcp", "memory",
"model", "pairing", "plugins", "postinstall", "profile", "proxy", "sessions", "setup",
"model", "pairing", "plugins", "postinstall", "profile", "proxy", "send",
"sessions", "setup",
"skills", "slack", "status", "tools", "uninstall", "update",
"version", "webhook", "whatsapp", "chat",
# Help-ish invocations — plugin commands not being listed in
@@ -10160,6 +10173,12 @@ def main():
)
slack_parser.set_defaults(func=cmd_slack)
# =========================================================================
# send command — pipe shell-script output to any configured platform
# =========================================================================
from hermes_cli.send_cmd import register_send_subparser
register_send_subparser(subparsers)
# =========================================================================
# login command
# =========================================================================