NousResearch/hermes-agent · Weekly · Jun 29, 2026 - Jul 05, 2026

Hermes-Agent Weekly: Multi-Terminal Panel, Shared WebSocket Layer, Security Hardening, and Live Agent Terminal Mirrors

Commits summarized
1,143
Period
Jun 29 - Jul 05, 2026
Published
Jul 06, 2026

Hermes-Agent Weekly: Multi-Terminal Panel, Shared WebSocket Layer, Security Hardening, and Live Agent Terminal Mirrors

Issue: Week of 2026-06-29 – 2026-07-05

This edition highlights the most impactful changes from ~200 commit summaries sampled from 1,143 total commits this week. If you're building on the desktop app, running Hermes in Docker, or deploying a multi-tenant gateway, the notes below cover what changed and why.

Desktop: Multi-Terminal Panel with Read-Only Agent Mirrors

The desktop terminal pane has been rewritten to support multiple persistent user terminals and live read-only agent background terminals — a major step toward VS Code-level terminal parity.

Multi-Terminal Panel & Tab Rail

  • Side tab rail: A thin VS Code-style icon rail on the outer edge of the terminal pane manages multiple persistent in-app terminals. Each tab is a live xterm+PTY that survives tab switches, session switches, and hiding the pane; only an explicit close or exit kills a shell. (6875d6c)
  • Visibility-based tab hiding: Inactive tabs use visibility: hidden (absolute-stacked at full size) instead of display: none to prevent ResizeObserver bailout and buffer garbling on re-show. (c1bb34d)
  • ⌘W closes focused terminal: The keybind now routes to the focused terminal tab (user or agent) via the new isFocusWithin primitive, preventing accidental preview tab closure. (2d55ff8, b02f453)
  • Forced repaint on reactivation: WebGL terminals don't paint while visibility: hidden; reactivation now clears the glyph atlas and forces a full refresh. (6e12f8c)
  • ⌘W closes agent tab: Agent mirror instances are marked data-terminal and focused on activation so isFocusWithin routes ⌘W to them. (e117cfd)
  • Close all action added to terminal tab context menu. (1a1e00f)
  • Ctrl-L injection removed: The prompt-gap cleanup that sent Ctrl-L into the user's shell is gone; it could render as literal ^L. Initial newline striping is now renderer-side only. (1a1e00f)

Read-Only Agent Background Terminals

  • Agent background tabs: When the agent runs terminal(background=true), it surfaces as a read-only "agent" tab in the rail (distinct sparkle icon). The status row links to the tab instead of an inline disclosure. (ad831dd)
  • Live streaming via push: Replaced the 5s output_tail poll with a real push stream from the process registry. Chunks route by process ID directly into the read-only xterm via a capped backlog. (520212c)
  • Snapshot seeding: Agent terminal tabs consume both live chunks and process snapshot data so they never open blank while output is pending. (6ac9ba9, 5d661a3, 7cfa2fa)
  • Agent-driven tab close: A new close_terminal tool (HERMES_DESKTOP-gated) drops a read-only tab without killing the process; output continues buffering. (e117cfd)
  • Scrollback parity: Agent terminal tabs use the same 1,000-line scrollback cap as user tabs and full unicode/WebGL rendering. (6c52e4a, adacb16)

Terminal Tab Persistence Across Relaunch

  • User terminal tabs and scrollback persist across app restart. Tabs, active selection, cwd, and serialized scrollback snapshots are written to localStorage (750ms throttle). Processes are NOT revived — a new shell starts below the restored history. (1c0fa12)
  • Teardown guard: pagehide/beforeunload flags prevent the persisted tabs from being wiped on quit. Agent mirror tabs remain runtime-only. (1c0fa12)

Infrastructure: Shared WebSocket Layer & Headless hermes serve

Extracted Shared WebSocket/JSON-RPC Client

  • The Electron desktop app and web dashboard now share a common @hermes/shared WebSocket+JSON-RPC client, eliminating ~210 lines of duplicated plumbing. The dashboard is a thin subclass with dashboard-specific auth selection. (dfb561a, 5a4bdfda)
  • Dashboard WS URLs centralized: All dashboard WebSocket endpoints now route through buildHermesWebSocketUrl. (6c52e4a)
  • Deterministic WS close: Intentional closes now reject pending RPCs immediately instead of relying on browser close events. (5a4bdfda)
  • Dashboard gains 15s connect timeout (previously desktop-only). (dfb561a)

New hermes serve Command

  • hermes serve is a dedicated headless backend command that boots the same gateway without opening a browser. The desktop app now spawns serve exclusively. (dff491a)
  • Backward compatibility: If the runtime doesn't register serve (older install), the desktop falls back to dashboard --no-open. (e684b80)
  • Contract tests added for the serve subcommand. (9d9a50c)
  • Documentation updated: Desktop README, docs, and AGENTS.md clarify the desktop is self-contained and never requires the browser dashboard. (f019a99)

Platform & Security Hardening

Docker: Cgroup Controller Fallback

  • Graceful degradation on cgroup-limited hosts: Container startup now probes for cgroup v2 cpu/memory/pids controller delegation and omits --pids-limit, --cpus, and --memory flags when they're unavailable (e.g., unprivileged Proxmox LXCs, rootless setups). Previously these hosts would fail every container start with an OCI runtime error. (7cfa2fa)

Terminal: Host-Bound Docker Approval

  • Docker containers with host bind-mounts now route through the normal approval flow instead of auto-approving all commands. Isolated Docker containers (no host paths) keep the fast path. (9860d93)

Credential Redaction

  • Bare-token URL credentials redacted: Git remote URLs with embedded passwords (https://PASSWORD@github.com) are now masked by the redaction engine. Previously only user:pass@ form was caught. (3483424)

Agent-Loop Hardening

  • Anthropic interrupt guard: Return None on interrupt instead of calling get_final_message() on a partially-drained stream (could hang or return incomplete tool_use blocks). (ec148f5)
  • Vision data-URL cap: 20 MB cap on base64 data-URLs before decoding to prevent OOM in shared gateway processes. Oversized payloads return ("", None). (ec148f5)

Gateway Exception Handling

  • Error notifications logged: The last-resort exception handler in _process_message_background() now logs with exc_info=True instead of a bare pass, making failed error-notification sends debuggable. (f1cbe43)
  • Sanitized error messages: Exception text from LLM providers (which can leak API URLs, file paths, credentials) is no longer sent to end users. A generic message is returned; full detail stays in logs. (27ddd8f)

File & Path Validation

  • Skills path containment fixed: Replaced string prefix check with strict path containment. (313a8c6)
  • Host/relative cwd sanitized: Before reaching a container sandbox. (8fe800e)
  • Webhook arg validation: pr_number and repo are validated before passing to subprocess. (27ddd8f)

Profile Alias Path Traversal Fix

  • Custom alias names are now validated against a profile-id regex (forbids /, ., ..) to prevent path traversal and arbitrary file write/unlink in the wrapper directory. (11183e8)

Config & .env Parsing

  • export prefix stripped: All three .env parsers now strip the bash-compatible export prefix, fixing silent auth failures for users who copy-paste from bash profiles. (5c1ac6c

LMStudio Base URL Normalization

  • LMStudio base URLs are now normalized. (163562b)

Gateway & Integrations

Session Boundary Fixes

  • /resume clears model overrides: Chat-keyed _session_model_overrides and _pending_model_notes are now cleared on /resume, preventing a model switch from a previous session leaking into the resumed conversation. (61a4526)
  • Cached agent eviction on auto-reset: The agent cache is now cleared on daily/idle/suspended auto-reset, preventing stale _previous_summary from mixing into compaction summaries in fresh sessions. (b4300f2)
  • AST invariant test pins the eviction into the auto-reset cleanup block. (0b733a8)

Approval Mode Validation

  • Unknown approvals.mode values now default to manual with a warning instead of silently behaving like manual with no signal. (dda3268)

Matrix & Mattermost Security

  • Matrix invite auth check: Invites now check the inviter against the allow-list before auto-joining, preventing federated users from inviting the bot into arbitrary rooms. (d836b2b)
  • Mattermost API path traversal guard: _api_get/_api_post/_api_put reject any path containing .., preventing authenticated requests to arbitrary endpoints via WebSocket-event value interpolation. (d836b2b)

WeCom Callback Body Cap

  • Raw request body size is now capped before pre-auth XML parsing on the internet-facing WeCom callback endpoint. (74541be)

Cron: False 'Gateway Not Running' on External Providers

  • cron status no longer reports a false negative for external providers like Chronos, which deliberately don't run a 60s ticker loop or write a heartbeat file. The provider is resolved offline and reports managed-scheduler state. (0943e2a)

Agent & File Injection

.hermes.md Parent Walk Scoped to Git Repos

  • Outside a git repo, only the current working directory is checked for .hermes.md/HERMES.md, preventing a file planted at /tmp, /home, or / from being loaded into every agent session as a cross-user prompt-injection vector. (306b661)
  • Regression tests added for no-git-root cwd-only and git-root walk behavior. (14204b0)

UI / Desktop Polish

Shared Overlay Panel Primitive

  • The Agents, Cron, and Profiles overlays now share a single Panel primitive (centered card, header, master/detail with built-in search, kebab row actions, "+" footer, empty state) instead of three ad-hoc layouts. (9912207)
  • Dead overlay code removed: OverlayNewButton, OverlayCard, and unused search-input module are dropped. (317b948)
  • Theme-var form controls: Input border/background/inset are now per-mode CSS custom properties. (9912207)

Dashboard: Memory Provider API Key Catalog

  • All six memory providers (Hindsight, Supermemory, Mem0, RetainDB, ByteRover, OpenViking) now have their API keys catalogued in OPTIONAL_ENV_VARS and appear in the dashboard Keys page. A contract test asserts every provider's primary credential key is catalogued, tool-categorised, and password-masked. (dee41d0)

Dashboard Backup Upload/Download

  • Dashboard backup download and upload is now supported. (476875a)

Gateway Status Popout & Command Center Polish

  • Live gateway log tail while the popout is open (WS connection churn filtered), flattened status header, and system-panel/restart actions. (6776b2f)
  • Command center: removed usage/system dividers, swapped session nav icon. (6776b2f)

Chore & Tooling

  • Committed PR infographics removed: 35 PNGs (~54MB) accumulated under infographic/ are deleted and the path is now gitignored. (43eaf79)
  • Prettier + ESLint pass across repo. (9f02eea)
  • Docker build fix: apps/shared included in dashboard Docker build context. (e9b95df)
  • export prefix stripping tests added for .env parsers. (490f215)
  • AUTHOR_MAP entries added for several salvage PRs. (163562b, 9cf9d3a)

Documentation

  • Cron delivery targets documented: Per-platform explicit target syntax for Slack, Matrix, Feishu, WhatsApp, Signal, SMS, Email, and Weixin is now fully documented in the Delivery Model table (en + zh-Hans). (e1f4098)
  • Desktop-backend relationship clarified in multiple docs pages. (f019a99)

This post covers highlights from 200 commit summaries of 1,143 total commits in the period. For a complete record, see the full commit log.

Repository updates

Follow future updates

Get generated NousResearch/hermes-agent development summaries by email, or follow the weekly and monthly RSS feeds.

Sign in to subscribe by email. RSS feeds are public.

Sign in to subscribe