Browse by topic

Hermes yesterday, October 19, 2026: the classic CLI gets a new look

What landed on Hermes Agent main on October 19, 2026: a new default look for the classic CLI, long-running gateways that stop going silent, /debug local that stays local, no more false tool failures, lost turns that stop jamming cron queues and 16 new catalog plugins.

Dark title card with orange, magenta and teal light streaks rushing toward a bright central slit, reading the CLI got a new look, its emoji came back within 3 hours, from the Hermes yesterday motion recap.

The classic CLI got a new look, lost its tool emoji, and had them back less than three hours later because people missed them. Also: long-running gateways stop going silent after a few hundred agent builds, and /debug local stops sending your debug report to a public paste. 455 commits landed on main; here are the 10 that matter.

1. The classic CLI gets a new default look

Before: the classic CLI (what hermes opens by default) drew reasoning and answers inside width-sized boxes, so resizing the terminal re-wrapped and garbled everything already printed, and the status bar sat above the input. After: on by default (display.cli_layout: modern), every scrollback row starts with one glyph and never depends on the width: ❯ for your message, reasoning that streams live and closes with a Thought for 3s line, one row per finished tool call with its classic emoji (a red ✗ and the exit code when it failed), the edit diff under its row, a plain ☤ Hermes answer that copies cleanly, and a summary line closing each turn (time, files edited and read). The spinner moves into the composer’s top rule, the status line moves under the composer next to the keys that work right now, and the welcome banner stays. While a turn runs, Enter keeps your busy_input_mode (interrupt by default) and Tab queues the message for the next turn. display.cli_layout: classic brings back the old look exactly. Not covered: the Ink TUI (hermes --tui) keeps its own look for now.

Pull requests: Glyph layout and subagent dock, Tool emoji back.

2. Long-running gateways stop going silent and stop leaking threads

Before: on a long-running gateway, every agent build followed by a background review stacked two more wrappers on stdout, and after about 500 builds every turn failed with RecursionError while the process still looked healthy, so systemd never restarted it and the bot simply stopped replying (one report: after 11 days on Telegram). Separately, a messaging gateway with an external memory provider kept a writer thread and a connection for every agent its cache evicted, so threads and file descriptors grew until a restart (a soak test grew about 1,400 threads on main and none with the fix). After: agent builds leave the existing wrapper alone, so the chain stays at one link however many agents are built. Evicted agents flush their queued memory writes and shut their providers down, and a hung provider no longer pins a thread per agent: once four calls are overdue (30 s for background calls), new calls to it are skipped with a warning, one probe every 60 s checks whether it is back, and at most 16 calls per profile and provider stay in flight. Heads-up: skipped calls lose those turns’ memory writes and recalls, and if 16 calls from separate outages never return, that provider stays off for that profile until the gateway restarts; the built-in memory is never gated. A narrow race in the same stdout code is still in review (linked below).

Pull requests: No more RecursionError, Memory provider threads, Stdout race, in review.

3. /debug local keeps your report on your machine again

Before: since the one-gateway change, /debug local typed in the CLI, TUI or Desktop went to the chat handler, which ignored the word local and uploaded the debug summary (system info and log tails, with API keys, tokens and passwords redacted but other personal data left in) to a public paste site; from a chat, /debug local uploaded it too. After: on a local session, /debug local shows the report on your machine with no network call at all; from a chat it is refused and points to bare /debug, which stays the upload form. Also for local sessions: /refine after /moa reviews the session’s stored transcript instead of coming back empty, the session’s owner can add a /goal gate, and /reasoning show|hide and /footer stick on every local surface (Desktop Settings follows them), while a chat’s /footer still sets the footer everywhere.

Pull request: /debug local and local sessions.

4. Successful tool calls stop showing up as failed

Before: the check behind the [error] tag in the CLI, TUI, Desktop and gateway still scanned the first 500 characters of a result for a quoted error or failed anywhere, so every successful web_extract call (it returns an error field set to null for each URL) was tagged as failed, and so was any call whose returned data merely held an error key, such as a browser_cdp read of a form’s validation messages; the same false failures could count toward the guardrail’s repeated-failure streak. After: a JSON result is judged by its top-level shape (success, error, a status of failed or error, or a batch where every item failed), and empty values such as null, false or 0 never count; plain-text results are still scanned. Replaying 200,000 real tool results, 12 stopped being flagged and none started.

Pull requests: Empty error fields, Top-level shape.

5. A restart no longer leaves cron and webhook queues stuck behind a lost turn

Before: when a gateway restart cut off a turn mid-run, that turn was marked unknown and paused the conversation’s whole queue until someone resolved it, even when nobody could: a cron run, a webhook delivery or a Kanban card attempt (one Bot Chat sat ten hours behind one). Chats were told to ask the operator, and the TUI showed a bare [unknown] tag. After: automation turns lost in a restart settle as interrupted with a notice, are never run again, and the queue moves on. A person’s lost turn still pauses, because only they know whether to resend it, but every surface now says why and offers to drop it in place: /discard in chats (/hermes discard on Slack), Ctrl+X on the TUI row, /discard with the turn’s id in ACP editors, and Desktop’s existing Discard card. A turn a restart interrupts now says Gateway restarting and that it will not be run again, and a viewer that reconnects after the restart still sees that notice. Not covered: a Kanban attempt started before the upgrade keeps the old pause, and /discard still needs a live retest on real messaging platforms.

Pull requests: Automation settles, /discard, Notices for reconnecting viewers, Kanban cards, Restart wording.

6. /resume finds your Telegram and cron sessions again, and Desktop stops flagging every chat reply

Before: since the one-gateway change, the terminal /resume picker listed only sessions started from a terminal or Desktop, so saved Telegram, WeChat and other messaging conversations and finished cron runs were missing; an older messaging conversation (after the chat’s /new) could not be deleted; a refused delete left the closed session listed as live; Desktop showed Session controls unavailable for a messaging conversation once its chat moved on; and every Telegram or WeChat reply lit Desktop’s unread dot and titlebar badge. After: messaging conversations (plugin platforms such as IRC, LINE and Google Chat included) and finished cron runs are listed again, a compressed conversation only once; older conversations can be deleted without touching the chat’s current one; a refused delete leaves the session as it was; Desktop reads the saved goal, loop and heartbeat after the chat moves on; and a messaging reply marks a session unread only when its message was sent from Desktop and you have not opened the session since. The Desktop-sent case is covered by tests, not yet checked live.

Pull request: Sessions and unread.

7. Classic CLI: /queue joins the gateway’s queue, subagents are back in the dock, –api-key is honored

Before: the classic CLI kept /queue items in its own process, apart from the queue Ink and Desktop use; since the one-gateway change its live-work dock and Ctrl+T monitor showed no subagents (they read an empty local list); hermes chat --cli ignored --api-key and --base-url and ran on the profile’s own key and endpoint; and the first turn after a gateway restart in a session started with --api-key failed with launch_credentials_unavailable. After: /queue during a turn goes into the gateway’s durable queue, survives a gateway restart and runs once, in order; /queue list, edit, rm and clear act on the session’s shared queue (other windows’ prompts and automation rows included), edit moves the item to the back, and move is refused. The dock and Ctrl+T show the gateway session’s subagents with steer and stop, and /review shows its reviewer there. Both flags now reach the classic CLI, and it resends its launch key when it resumes or reconnects; a typed --api-key the resumed session was not launched with is refused at startup. Image follow-ups still queue locally.

Pull requests: Durable /queue, Launch key on resume, –api-key and –base-url, Subagent dock.

8. Desktop and TUI slash commands work on the shared gateway again

Before: since the one-gateway change, Desktop refused /rollback, /agents, /config, /history, /export, /import, /timestamps and /palette or called them terminal-only, and /save wrote a JSON file on the gateway’s machine; the TUI refused /voice, /reload-mcp, /config, /save and /timestamps or ran them on the old backend. /undo or /retry during a reply showed a bare error: session_busy, and editing a message whose reply you had just stopped sent the edit as a new message, so the stopped message and its partial reply went to the model again. After: those commands run on the gateway; /save renders json, md or html (optionally redacted), Desktop writes it through a native save dialog and the TUI writes it in your folder; Desktop’s /config shows only display, approval and voice-key settings, never credentials or provider sections; and commands that act on the gateway machine’s disk or terminal (/snapshot, /worktree, /handoff and others) are refused by name with what to use instead. /undo and /retry mid-reply say to stop the reply first, or to wait when a /compress holds the conversation, and an edit after a stop replaces the message. Also in Desktop: subagent provider and model move to Settings, Model, Subagents as dropdowns saved only on Apply; a /steer stays where you sent it, above the answer it causes; and with Read replies aloud on, the final reply after tool calls is spoken again. Not covered: /export and /import on a remote gateway are refused by name for now.

Pull requests: Desktop commands, TUI commands, /undo, /retry and edit after stop, Subagent picker, Steer placement, Read aloud after tools.

9. Plugins: update everything at once, and sign in without handing over tokens

New: hermes plugins update with no name lists every installed plugin with an update (catalog re-pin or git pull), asks once and updates each one through the normal single-plugin path, so new capabilities and widened pins still prompt per plugin, and one failure no longer stops the rest. Without a terminal it updates nothing unless you add --yes, and then new capabilities stay ungranted and widened pins are not applied; pip-installed plugins are skipped and Desktop has no update-all yet. For plugin authors: a plugin can declare OAuth clients in plugin.yaml, hermes auth add <plugin>:<id> runs the browser sign-in (PKCE) and keeps the grant in the profile’s auth.json, and the plugin calls the API through Hermes, which attaches the token only for the declared hosts over https and never hands it to plugin code; after a security review, errors carry no credential, sign-in is refused where nobody can answer (gateway, cron) and removing the plugin drops its grant. Portable plugins (plugin.json) now get a Settings, Plugins form, and a newly saved API key reaches the plugin’s running MCP server without a restart. In an MCP server’s env (config.yaml and plugins alike), an entry that is just ${VAR} with VAR unset or empty is now treated as if the line were not there, instead of passing the literal text; a partial reference such as ${VAR}/bin still passes as is.

Pull requests: Update all, Plugin OAuth, Settings form and key reload, Optional MCP env, MCP env follow-up.

10. 16 new plugins in the catalog: memory leads

16 new community entries, and long-term memory was the day’s theme: hosted versioned memory (bilinc), a self-hosted memory daemon (post-cortex) and search across the sources your company connected to Gurusup (gurusup-brain). Several disclose that they send data to a hosted service (anyapi relays your prompts, tool results and key through api.anyapi.ai) or run local tools with your logins (git-tasks runs your signed-in gh CLI): read the disclosure before installing. Catalog entries do not wait for a release: they go live once the published catalog refreshes.

Meanwhile, in the engine room

Dozens of fixes landed yesterday that most users will never see, and the shared gateway took most of them again, with the CLI and Desktop close behind.

  • Image and video generation through the Nous tool gateway polled the FAL queue every 0.1 s, so one image could spend the gateway’s whole 200-requests-a-minute budget and a second job got 429s; it now polls every 2 s, adding at most 2 s of wait (pull request)
  • On a multi-profile gateway, starting the API listener silently stopped agent.log, errors.log and gateway.log for every profile until the next restart; the log files keep writing now (pull request)
  • On a multi-profile gateway with persistent Docker, a secondary profile’s /bg side agents and worker turns ran in the default profile’s container, with its /root, mounts and settings; they now run in their own profile’s (pull request)
  • With browser.use_real_profile on, Windows users had to quit Chrome every time Hermes opened a browser; a locked profile now reuses the last finished copy of the same profile, with logins as of that copy (pull request)

If you noticed none of this, it worked.

All on main, ships in the next release. Latest stable: v0.22.2.

Watch the recap

The 56-second motion recap, made with Remotion, is on X.

Was this configuration guide helpful?

If you have questions, encountered issues during setup, or want to discuss networking and security, connect or reach out on LinkedIn.

Connect on LinkedIn