ELPA Logo NonGNU ELPA: hermes

hermes Atom Feed

Description
Emacs frontend for Hermes Agent
Latest
hermes-0.8.0.tar (.sig), 2026-Oct-02, 2.21 MiB
Maintainer
Thanos Apollo <public@thanosapollo.org>
Other versions:
development version
Website
https://git.thanosapollo.org/emacs-hermes
ELPA's Repository
CGit or Gitweb
All Dependencies
keymap-popup (.tar)
websocket (.tar)
markdown-mode (.tar)

To install this package from Emacs, use package-install or list-packages.

Full description

hermes.svg

An Emacs front-end for Hermes Agent, driven over the dashboard/TUI gateway.

1. Installation

Hermes Agent with dashboard/TUI gateway support is required.

1.1. NonGNU ELPA

hermes is available via NonGNU ELPA.

Install it with M-x package-install RET hermes.

1.2. package-vc (Emacs 30+)

(use-package hermes
  :vc (:url "https://git.thanosapollo.org/emacs-hermes" :lisp-dir "lisp")
  :custom (hermes-dashboard-transport-url "http://127.0.0.1:9119"))

2. Usage

M-x hermes opens the dashboard. M-x hermes-project-chat switches to a live chat for the current project or creates one at its root; with C-u it always creates another. Project-chat names stay anchored to that launching project while the header reports the gateway working directory. Customize hermes-chat-buffer-name-function to replace the default complete naming convention. A direct or resumed remote chat uses the editor directory in its initial buffer name while its gateway cwd is unknown. Its header stays detached, and the editor path is not sent to the gateway. M-x hermes-chat always opens a new chat buffer:

  • RET to send.
  • / for slash commands.
  • C-c C-o for the actions menu.
  • Each chat pins its resolved spawned or remote transport mode. A spawned chat starts from the editor's default-directory; a remote chat does not.
  • Passive gateway cwd updates change the header and a direct chat's buffer name, but leave default-directory alone.
  • “Set directory” browses or accepts a path in the gateway's namespace. On success, the backend-returned path becomes both the gateway cwd and the buffer's default-directory; a project chat keeps its launch-root name.
  • C-c C-o M m (or bare /model) fetches model choices from the owning dashboard each time. /model argument completion stays cached and nonblocking; opening the picker refreshes that cache after backend changes. The profile browser's model picker also fetches fresh choices each time. Failed fetches do not offer stale cached choices. The dashboard may maintain its own provider catalogue cache.
  • M-x hermes-close closes local connections and Hermes buffers for restart, discarding the frontend model catalogue cache. Reconnecting alone retains completion data; the picker still fetches anew.

Hermes commands declare their buffer contexts for native M-x completion. To filter completion candidates by context, set read-extended-command-predicate to command-completion-default-include-p. Hermes leaves this user option unchanged; with nil, all commands remain listed. Dashboard, chat, browser-opening and setup entry points stay available globally. Context filtering does not change key bindings or prevent direct invocation; commands retain their existing runtime checks.

Point hermes-dashboard-transport-url at your running dashboard:

hermes dashboard --no-open --tui --host 127.0.0.1 --port 9119

To use more than one dashboard, configure named instances:

(setq hermes-instances
      '(("local" . "http://127.0.0.1:9119")
        ("remote" . "https://dashboard.example.org")))

Commands prompt for an instance only when the current buffer does not already own one. Chat buffers retain their original instance and resolved transport mode, so later configuration changes cannot reroute them. Chats against different dashboards can stay open at the same time. Browser views retain their chosen instance until explicitly reopened for another one.

2.1. Kanban task bodies

Use E in a Kanban board or task detail to open the selected task's body in an independent multiline draft. C-c C-c saves only the body and reads the same task back; C-c C-k discards the draft. Empty bodies and Unicode are preserved. Saving uses the backend's last-write-wins behavior and can overwrite concurrent body edits; it does not resend title, status or assignee fields.

The draft retains its original board, task and backend. Changing or closing that source view retires save authority; copy the retained draft into a newly opened editor if needed. Failed or unverified saves retain the text and are never automatically retried. Check the board before manually retrying an uncertain update. A deleted task is not recreated.

Task details display literal Markdown with guarded programming-language highlighting. Fence labels cannot select arbitrary minor or global modes; copying preserves markup, and outline navigation remains available.

2.2. Agent plugins

M-x hermes-list-plugins opens the installed agent-plugin inventory. Use C for the curated catalog, RET for details, a to install the selected catalog entry, and I to return to installed plugins. The existing i command still accepts a plugin identifier or Git URL.

Details show repository, subdirectory, tier, full catalog pin, declared tools/hooks/middleware, environment requirements, and supported platforms. Tier describes provenance, not a safety guarantee. Installation can install dependencies and run code on the backend. It targets that dashboard's launch-profile home, not a profile selected in another view or chat.

Catalog installation resolves the entry again on the backend. The displayed pin is informational: Hermes Agent 0.21.4 does not honor ref for catalog installs, so Emacs does not send an override. Check the returned Installed SHA in details after installation. Emacs reads back both the catalog and installed inventory; it does not force replacement or automatically enable the plugin. Existing enablement can persist. Configured state is not proof of runtime activation.

If Update reports that new capabilities need consent, the Plugins header shows Awaiting capability consent. RET displays an inert handoff with the candidate SHA and declared additions. The receipt reports that the update was not applied. Emacs sends no consent retry: review the fresh candidate using the backend's native workflow, or leave the review to decline. Use g to refresh explicitly; a refresh never replays the update.

2.3. Named custom endpoints

M-x hermes-endpoints lists named endpoints on the owning dashboard. It retains the profile of a chat or onboarding view; other origins use the dashboard's launch profile. Use c for a new draft or RET to edit a saved row, then e to edit individual fields and k to choose Preserve, Replace or Clear for the API key. Keys use masked input, never minibuffer history or list text. Preserve omits the key from Save; only Clear sends an empty key. Stored keys are not fetched. Replace refuses values that would become empty under Hermes Agent 0.21.4 storage: boundary whitespace is stripped, then CR/LF and non-ASCII characters are removed. Refusal retains the previous key policy and draft. Accepted keys are sent literally, but backend storage can still change them; saved metadata is not proof of a usable credential or successful authentication.

In a draft, t requests explicit consent before Test. The dashboard sends the entered credential to the destination, may probe alternate /v1 paths, and may perform chargeable inference: one output token for Chat Completions or Messages, or up to 16 for Responses. Test neither saves nor activates. Its observations are not proof of successful inference or authentication: the transport check accepts 401/429 responses and inconclusive timeouts. The resolved URL is shown without changing the draft; u explicitly adopts it and the advertised model metadata.

s confirms Save with make_default:false. This is last-write-wins upsert, not an atomic edit: it can recreate a concurrently deleted endpoint. The backend merges unknown settings and existing model metadata. Unedited API mode and context length are omitted to preserve them; model discovery is sent explicitly. Editing an already-active provider can affect future runtime use even without Activate. Inspect the saved list and active model configuration read back below the retained draft; backend normalization can change names, URLs, IDs and model aliases.

Back in the list, a separately confirms Activate; d confirms Delete and possible detachment of the active provider's URL and credentials. g reconciles state, including after a failed or uncertain write; writes are never automatically retried. ? shows actions in either view.

Legacy/direct-config rows remain read-only. Stored IDs such as has.dot, -edge and edge_ support Activate/Delete and are sent unchanged. Hermes Agent 0.21.4 can leave the active-model mirror attached for IDs containing ASCII spaces (for example Mixed endpoint) or beginning with custom: (case-insensitive). Boundary whitespace can select a different stored key; slash-containing IDs and the whole IDs . and .. are not addressable by this route. Activate/Delete refuse those hazards before confirmation. The client does not rename IDs or repair backend configuration silently.

2.4. Gateway restart handoff

H in Configuration, Agent plugins, Messaging, or Status/Logs opens hermes-system-restart-handoff. It is also in the dashboard's System menu. The handoff retains the selected backend and explains the external operator action; it does not save, restart, run a shell command, or replay a configuration write.

Saved-value readback and runtime adoption are separate. Adoption and actual service/profile impact remain unverified: a named profile may share a multiplexer with other profiles and active sessions. Open the displayed dashboard URL separately and use its gateway controls, or ask that backend's operator to identify the service and arrange a safe restart.

The handoff's s (Status) and l (Logs) open read-only observations for the captured endpoint. After external action, g explicitly refreshes them; reported fields are not proof of a scoped restart or configuration adoption. If the originating view or handoff is replaced or retargeted, reopen the handoff rather than using its stale actions. Observation actions attach to the captured URL; they never auto-start a local service, even for loopback addresses.

2.5. Foreign histories

In Sessions, F opens the serving backend's Claude Code and Codex histories. Choose the destination profile and source. This does not scan the Emacs host. > requests the next page, including after an unreadable-only page. RET opens an inert tail preview, bounded by the backend to 40 turns and 8000 characters per turn; backend directory labels are not local links.

Previewing never imports. i asks for confirmation before importing into the displayed destination. Only after the returned stored session is read back from that profile does RET offer native resume. Preview refresh and canceling another import confirmation preserve that verified session; changing the preview's backend, destination or history does not. If the legacy default backend URL changes, reopen from Sessions before previewing or importing again. Once resume opens a chat, acquisition and reconnect retain that chat's selected backend, even if a mode or display hook changes the legacy default URL. An interrupted import can have an uncertain outcome: use g to inspect before explicitly retrying. There is no automatic import retry.

2.6. Context budget

From a connected chat, C-c C-o X b (or M-x hermes-chat-context) opens an on-demand context snapshot for that exact runtime session. g explicitly refreshes it; there is no polling. Computing a snapshot can rebuild backend prompt blocks and invoke memory hooks, even when computation fails.

The view keeps backend category estimates separate from reported usage and its source. Unbuilt categories and missing file information remain unknown, not zero-cost claims. Context-file paths are inert backend labels; they are not visited on the Emacs host.

2.7. Local dictation and read-aloud

C-c C-o A opens local audio actions in an attached chat: r records, s stops and transcribes, c cancels, and a reads a chosen settled assistant reply aloud. Nothing listens or plays automatically.

Configure hermes-audio-recorder-command and hermes-audio-player-command with trusted local foreground programs. Both default to nil; chat works without them. The recorder must write audio to stdout and finalize on SIGINT. The player receives a private local file in place of its %f argument. For example, with ALSA and ffplay installed on the Emacs machine:

(setq hermes-audio-recorder-command
      '("arecord" "-q" "-t" "wav" "-f" "S16_LE" "-r" "16000")
      hermes-audio-recording-mime-type "audio/wav"
      hermes-audio-player-command
      '("ffplay" "-nodisp" "-autoexit" "-loglevel" "quiet" "%f"))

Recording and read-aloud ask consent and identify the backend and profile. Devices belong to the Emacs machine, even with a remote dashboard. Audio bytes, not local paths, go to that chat's backend transcription relay. The result is a draft, never an automatic message. If you edit the draft while waiting, the transcript opens separately for manual copying. Silence leaves the draft unchanged. Read-aloud uploads only the reply you choose and plays the returned bytes locally; it does not retrieve provider credentials.

The defaults allow 8 MiB and 120 seconds per recording or playback. WAV, FLAC, Ogg, MPEG and WebM are supported; the recorder's MIME must match its output and the player must support the returned format. A time limit cancels rather than uploads. Stop gives the recorder two seconds to finalize. Cancellation or chat retirement stops owned local processes, removes private playback files and ignores late replies. It cannot revoke an upload or cancel a provider request already running. Limits need Emacs event-loop progress; response size is checked only after HTTP retrieval. Audio captures an absolute, local temporary-file-directory before consent. Later changes to that option cannot redirect recording or playback. Handler-managed scratch is refused, including when a file-name handler appears while waiting. Backend audio providers must be configured separately. These relays require Hermes Agent 0.21.4 or a compatible API.

2.8. Browser-vault prompts

Hermes Agent 0.21.4 browser-vault requests use native minibuffers: masked password-manager unlock, save-login password and verification code readers, plus an identifier reader without input history. Use C-c C-a to answer a pending request. Each reader shows the owning backend endpoint and the site/origin or password manager supplied by that backend. Empty password/code or C-g declines a current request; expired or disconnected requests cannot send or recover an answer.

Credentials go directly to the original backend request, never to chat input. The backend owns origin verification, credential storage and browser filling; Emacs does not run a local password manager or control its local browser. Minibuffer input, including indirect aliases sharing its text, is excluded from capability listings and reads even when the optional buffer-denial policy is disabled. Native kill/copy operations use a private kill ring and yank menu. Expiry revokes response authority immediately; an unrelated nested reader or recursive edit can finish before the expired vault reader is dismissed. This is not memory zeroization or a sandbox against trusted Emacs Lisp. Card/address collection is unsupported.

2.9. Headless prompts

(hermes-request REQUEST RESOLVE REJECT) returns a cancellation thunk. Require hermes-request for use without the UI. For example:

(hermes-request '(:prompt "Explain spaced repetition." :profile "study-eval")
                (lambda (text) (message "%s" text))
                (lambda (reason) (message "Request failed: %s" reason)))

The profile must exist in the selected backend catalogue with a configured model and provider. Each request captures those exact choices from a fresh catalogue read, overriding backend launch defaults without changing profile configuration. Missing or malformed choices fail before session creation; credentials and any configured fallback policy remain backend-owned. Each call creates a fresh hidden session; no current chat history is used. Only a successfully completed final response reaches RESOLVE; cancellation, timeout, disconnect, or required interaction reaches REJECT. hermes-request-timeout bounds the request. Closing the session is best effort and does not delete backend history. A fresh session and profile/model selection isolate conversation context, not tools or filesystem access. This client does not verify the agent's effective tool set; an empty configured tool selection is not a no-tools guarantee on the supported gateway. For evaluation that must not affect the host, use an independently isolated backend. Profile configuration alone is not a sandbox.

2.10. Local text/source attachments

Use Compose → Attachments → Upload text\/source or M-x hermes-chat-attach-file in an already connected, attached chat. This separate action leaves image attachment and path completion unchanged. It accepts up to 2 MiB of local UTF-8 text/source with a supported suffix; PDF extraction and arbitrary binary files are unsupported. Local reads are bounded; the underlying HTTP response retrieval is not streaming-bounded.

The command captures the owning session's gateway-host working directory, requires managed Files policy admission, and asks before attempting a write there. Upload checks write permission. This does not establish equivalence with a remote terminal backend. A generated filename reduces collisions but overwrite:false is a non-atomic backend precheck, not exclusive creation. Exact byte readback precedes the owning session's file.attach(path) call. Only its validated reference is appended to an unchanged composer; nothing is sent. Paths refer to current content and can change before a later Send.

A native recovery view retains the original literal draft, bounded bytes and any returned reference. Oversized files retain only an explicitly labelled incomplete prefix of 2 MiB plus one byte; the unread tail is not recovered. Newer draft edits, cancellation, ownership changes and uncertain failures never replace text, retry an upload, or delete a remote file. Use s in recovery to save exact bytes to a new local file, then copy a reference manually if appropriate. Attachments → Reopen retained recovery opens retained data afresh without repainting a view reused for notes. Data is retained in memory only: save it before closing recovery views or Emacs. At most eight live recovery views are retained per chat. Uploaded files may remain after failure or cancellation; cleanup is a separate explicit action.

2.11. Output previews

Completed tool outputs with published file paths, and closed HTML/SVG code blocks in assistant replies, offer [Preview] buttons. The chat actions menu also provides Workspace → Preview output. Previewing never reads a backend path from the local filesystem: it requests current bytes from the owning chat's managed-files API, with a 4 MiB limit. The server's file policy may refuse paths outside its managed root. Failed reads offer retry and copy-target commands; remote URLs are copyable but never fetched automatically.

Previews are inert. HTML loses scripts, links, forms, attributes and external resources; SVG renders only an explicitly supported passive subset. Use v to switch to retained source, s to save the exact bytes to a new local file, g to retry, y to copy the target, and q to quit. Raster display depends on Emacs image support; unavailable previews retain source or binary metadata and the save action. For rendered raster images and passive SVG, + and - zoom between 10% and 400% of the initial displayed size; 0 restores that size. Zoom requires native image scaling and never fetches or changes saved bytes. Source toggling and zoom wait for a pending read; use C-g to cancel it first. File paths refer to current content, not historical versions: the backend does not publish reliable artifact revisions.

2.12. Skills: installed content and Hub previews

In the Skills inventory, RET or f opens the selected skill's SKILL.md from that backend's launch profile. The text is read-only until C-c C-e (Edit). Use C-c C-c to save, C-c C-k to discard local edits, and C-c C-h for help. Save replaces the whole document: it can overwrite concurrent changes. A matching backend readback confirms the save; errors, validation refusals and uncertain outcomes leave your draft intact. Nothing retries a write automatically. C-c C-g reads again after local edits have been saved or discarded. Backend paths are labels, not local file targets. These controls do not create skills or edit supporting files, and saving does not claim to activate changes in a running session.

H in inventory, or M-x hermes-skills-hub, opens the separate optional Skill Hub. Use n/p to move, f or RET to preview, b to return, s to search configured sources, S to inspect source availability, and P to choose a backend profile. Rows retain their source and identifier, even when names match. Search is bounded; timed-out sources are reported as partial results. Preview shows inert SKILL.md text and supporting file names only—not a review of those files.

In a preview, S requests a scan only after confirmation. Scanning can fetch and quarantine files on the backend and run an optional external scanner. Allow, ask and block are policy results, not safety guarantees; an absent or failed advisory scan is not a pass. Browsing and previewing never install, enable or execute a skill. These views require backend REST support and have no local command fallback.

2.13. Live tasks

Use Workspace → Live tasks in the chat actions menu, or M-x hermes-chat-show-todos, to open the session-owned checklist. It follows backend task snapshots without changing the chat draft or moving focus. The panel is read-only: pending tasks stay pending when a turn ends, with settled or stale labels rather than invented completion. Backends without a restored task snapshot can still populate the panel from live tool results.

2.14. Conversation commands and file references

/btw QUESTION asks a side question over the current conversation without changing its main history. /bg TASK (also /background) instead starts an independent background task. Both deliver persistent result links while the main turn can continue. A rejected or uncertain side question is retained in a separate *Hermes side question* buffer, never in the send queue. Inspect results before manually copying it into a new /btw command; recovery does not retry the question or replace a newer draft.

/branch [NAME] branches the attached, idle conversation through the backend and opens the child with its history in a separate chat. The parent and its draft remain available. If a branch fails after backend creation, the child may still exist; inspect Sessions before retrying.

Composer @ completion reads the attached session's backend workspace, not Emacs's local project. Try @src/mo, @file:src/mo or @folder:src and invoke completion again after the asynchronous lookup finishes. Accepted candidates become explicit, quoted backend references. Paths that cannot be represented by the backend parser are not offered. This is reference completion, not a local-file upload; literal bare @path text does not attach file contents.

New remote chats with no selected directory inherit the selected profile's backend workspace. Emacs records the returned directory without changing its own default-directory. Deliberately selected directories remain explicit.

2.15. Session pins and named workspaces

In M-x hermes-list-sessions, k toggles the selected session's server pin. If the pin is unknown, the first press reads it without changing it. The same action is available in session details; M-x hermes-sessions-pin and M-x hermes-sessions-unpin set it explicitly. Emacs reads the stored session back after each change. A failed read leaves the pin unknown. Use l for a profile's stored catalogue and > to load its next window.

M-x hermes-list-projects opens the backend's named, multi-folder workspaces in that dashboard's launch profile, also available from the dashboard and command palette. Use RET for details, P to change backend profile, and ? for create, rename, archive/restore, folder, and active-project actions. Explicit profile names must match that backend's current profile catalogue exactly; unavailable catalogues block those scoped requests. This preflight cannot prevent a profile from being deleted on the backend during dispatch. Folder prompts accept backend paths, without local file completion. Grouped sessions come from the backend's bounded subset, not a complete session archive.

Projects are metadata: selecting an active project does not move sessions, and deleting a project keeps its directories and sessions. Named backend projects are separate from the editor project used by hermes-project-chat. To change an attached chat's working directory, use its Set directory command. Stored-session moves are unavailable because the backend can confuse live sessions with the same stored ID in different profiles. Older backends without project methods show an unsupported status; ordinary session browsing remains available.

2.16. Hosted Group Chats

M-x hermes-list-groups reads rooms hosted by the selected backend. The dashboard's Browse menu also offers H for Group Chats. Use RET or f to open a room, m for the next list page, and g to refresh or reconnect. Public messages show their speakers in sequence order; member activity, task counts, and pending approvals appear separately. With a ready hosted driver, c creates a room from two to six existing profiles on that same backend. Open the room and use s to send a literal message in a named thread. The roster shows mention handles; the backend owns mention policy, rounds, member sessions and durable work, not Emacs.

Send acceptance is separate from completed member turns. If a receipt is lost, R reconciles the retained submission against the room log before offering an explicit retry with the same event ID. No submission or task is retried automatically on reconnect. Keep the view open to retain an uncertain message's recovery identity; closing it discards that local copy.

a answers an exact pending approval (once or deny). x requests cancellation for this room and reads state back; it does not terminate the gateway or claim that every process stopped. r explicitly retries a named uncertain task, including work the backend has deferred, after warning that the prior execution may have had effects. Before offering or answering an approval, Emacs reads complete room history and excludes retired tasks and executions, so historical failures do not block fresh requests. Incomplete history, ambiguous task authority, or stopping work refuses approval; use g to continue reading. State, history and approval are separate backend calls, not an atomic transaction with other clients. Closing the view or Emacs only stops local monitoring: backend work can continue.

The backend must advertise the protocol-2 room-reading methods and features. Driver availability is shown separately: stored history can remain readable when the worker is unavailable. F toggles five-second activity refresh and keeps its own connection reference, even without an open chat. Turning it off, closing or repurposing the view, transport retirement, terminal room state, or three consecutive read failures releases that reference. g resumes from the last rendered cursor; failed rendering retains the accepted text and cursor. Each refresh reads at most 20 log pages; g continues larger histories.

Authority changes restart replay explicitly. A sequence gap triggers a state check, not a skipped range. Disbanded history stays marked as such; expired history is a retained local snapshot, never a revived room. These are gateway-owned rooms, not the desktop's legacy localStorage rooms.

3. Bot Chats and routines

In M-x hermes-list-profiles, RET opens the selected profile's canonical Bot Chat. Emacs looks up that exact title on the selected backend, including hidden history and its compression continuation. Only confirmed absence offers creation. A new conversation stays hidden and follows profile configuration; its title must be persisted and read back before the chat opens. Failed or contradictory lookup never creates another conversation. Opening sends no introduction, though the backend can prewarm the agent and discover MCP tools.

N opens a separate ordinary scratch chat. Within a canonical Bot Chat, /new offers compression or explicit scratch creation; it does not silently replace the relationship. Ordinary chats retain their existing /new behavior. m still edits the profile's default model.

R opens that backend/profile's existing cron jobs in the ordinary cron editor. Opening or refreshing Routines only reads jobs. Creating, editing, pausing and running a job remain explicit cron actions; there is no separate scheduler or automatic Bot Chat delivery preset.

Canonical chats, scratch chats explicitly opened by their /new command, and Routines retain the backend selected when opened, including after reconnect or changes to the default dashboard URL. Routines actions and run transcripts stay on that backend. Reopen from Profiles to choose another backend; ordinary chats and the all-jobs cron browser keep their existing endpoint-selection policy.

4. Dashboard authentication

hermes-dashboard-transport-remote-auth-method defaults to auto:

  • With auto start mode, loopback dashboards spawn without extra credentials.
  • With remote start mode, an ungated dashboard at 127.0.0.1 can supply its session token automatically. Emacs reads the dashboard's HTML asynchronously; no shell command or environment change is needed.
  • Remote or gated dashboards probe /api/status. Auto authentication uses valid stored basic credentials first, otherwise native PKCE when advertised, and reports missing basic credentials for a basic-only dashboard.

Automatic discovery accepts only 127.0.0.1, never DNS names (including localhost), other addresses, or redirects. Use 127.0.0.1 rather than localhost for credential-free attach. Explicit token arguments, auth-source entries, and HERMES_DASHBOARD_SESSION_TOKEN take precedence, in that order. Discovered tokens stay in memory for their dashboard endpoint. Reconnect reads a fresh token after a backend restart; a REST GET rejected with HTTP 401 may retry once. Writes are never replayed automatically. Failed basic/native login never falls back to discovery.

Supported gated attach paths:

  1. Basic/password — auth-source entry with port hermes-dashboard-basic, login username, and password secret. Emacs posts password-login cookies and mints a WebSocket ticket.
  2. Native PKCE OAuth — when /api/status advertises native_pkce, Emacs opens the system browser, completes the official /auth/native/* loopback flow, stores access/refresh tokens in auth-source under login/port hermes-dashboard-native, authenticates REST with Authorization: Bearer, and mints a short-lived WebSocket ticket. Failed or cancelled login does not overwrite prior stored tokens.
  3. Legacy session token — auth-source entry with login/port hermes-dashboard-token and the token as secret, or environment variable HERMES_DASHBOARD_SESSION_TOKEN. Used for ungated dashboards and forced token mode.

Force native, basic, or token to bypass auto selection:

(setq hermes-dashboard-transport-remote-auth-method 'native) ; or 'basic / 'token / 'auto

Generic auth-source examples (replace host/port/values; never commit real secrets):

machine https://dashboard.example.org:9119 login hermes-dashboard-native password {"access_token":"…","refresh_token":"…","expires_at":0,"provider":"oauth","user_id":""}
machine https://dashboard.example.org:9119 login admin password s3cret port hermes-dashboard-basic
machine https://dashboard.example.org:9119 login hermes-dashboard-token password SESSIONTOKEN port hermes-dashboard-token

If a gated dashboard advertises neither native_pkce nor a basic provider, Emacs refuses attach with an actionable error. Cookie-only browser OAuth without native_pkce remains unsupported.

5. Optional Emacs bridges

The dashboard/TUI connection above drives chat and management. Two separate, optional paths let Hermes call into Emacs:

  • hermes-capabilities is the native dashboard capability-provider path.
  • hermes-exec is the HTTP eval endpoint used by the external stdio MCP bridge, hermes-emacs-plugin.

To use the stdio MCP bridge, install it from Git, enable the endpoint, then copy its registration command:

pipx install git+https://git.thanosapollo.org/hermes-emacs-plugin
(require 'hermes-exec)
(setq hermes-exec-enabled t
      hermes-exec-host "127.0.0.1"
      hermes-exec-require-approval t)
(hermes-exec-start)
;; M-x hermes-exec-show-bridge-command

The generated command registers the packaged hermes-emacs-mcp entry point. For a non-loopback private address, also set the same EMACS_EXEC_TOKEN for Emacs and the bridge. Do not expose the eval endpoint on a public interface.

Desktop notifications default to completed chat replies, terminal chat errors, input requests, background-task results, and Kanban states that need attention. Cron failures use the same policy when cron failure monitoring is enabled. They are suppressed when the target buffer is already visible on the focused frame. Customize the event set, or set it to nil to disable notifications:

(setq hermes-notifications-events
      '(chat-reply chat-error prompt background
        kanban-attention cron-failure kanban-done))

Old versions

hermes-0.7.1.tar.lz2026-Sep-17 290 KiB
hermes-0.7.0.tar.lz2026-Sep-14 278 KiB
hermes-0.6.0.tar.lz2026-Sep-09 505 KiB
hermes-0.5.0.tar.lz2026-Sep-05 420 KiB
hermes-0.4.3.tar.lz2026-Sep-01 369 KiB
hermes-0.4.2.tar.lz2026-Aug-31 366 KiB
hermes-0.4.0.tar.lz2026-Aug-29 360 KiB
hermes-0.3.3.tar.lz2026-Aug-24 352 KiB
hermes-0.3.2.tar.lz2026-Aug-17 323 KiB
hermes-0.3.1.tar.lz2026-Aug-15 318 KiB
hermes-0.3.0.tar.lz2026-Aug-14 307 KiB
hermes-0.2.1.tar.lz2026-Aug-13 297 KiB
hermes-0.2.0.tar.lz2026-Aug-13 250 KiB

News

1. Version 0.8.0 (2026-10-01)

  • Negotiated server-to-client JSON-RPC requests for approvals, clarifications, sudo and secret prompts. Native readers answer the captured request once; expired or disconnected requests cannot affect a replacement session. Legacy prompt handling remains available. Terminal-read requests remain unsupported.
  • Added native browser-vault login, unlock and verification-code readers. Sensitive responses bypass the chat transcript and shared kill history; credential views are excluded from optional buffer capability reads.
  • Added hermes-chat-attach-file for bounded UTF-8 text/source files up to 2 MiB. It uploads into the owning session's gateway-host workspace, verifies byte readback, and inserts the returned reference only while the original draft is unchanged. Failure or uncertainty retains bytes and draft text for manual recovery, with no automatic upload replay or remote rollback. PDF extraction and arbitrary binary files are unsupported; gateway paths do not establish terminal-backend filesystem equivalence.
  • Preserved selected-profile workspace defaults during session creation and reconciled deliberately chosen directories before overrides or first input. Passive backend directory updates do not change the editor's directory.
  • Added explicit import of foreign histories and an on-demand context-budget view. Import retains the serving backend and profile; estimates and partial file manifests are labelled rather than presented as reconciled usage.
  • Added backend-owned hosted Group Chats with typed history, activity and explicit room/work actions. Reading a room does not start work; mutations require the advertised protocol and current gateway authority.
  • Added canonical profile Bot Chats and scoped routine navigation. Opening a routine neither creates a replacement session nor triggers its job.
  • Added an optional Gnosis handoff and native tutoring linked to an existing ordinary conversation. Gnosis owns questions, grading and accepted results; Hermes supplies teaching through normal chat without replacing its draft.
  • Added installed skill-content editing and source-qualified Skill Hub previews and scans. General Hub installation remains disabled until the backend can prove target scope and installation outcome.
  • Added plugin catalog browsing and an explicit capability-consent handoff. Enabling, updating and removing plugins retain their original instance and verified target; catalog tiers do not imply a security guarantee.
  • Added named endpoint saving, probing and explicit activation as separate actions. An inert gateway-restart handoff shows operator guidance; it does not restart a remote service or replay work.
  • Discovered dashboard tokens only for explicitly configured literal IPv4 loopback endpoints, without redirects, cookies or disk caching. Configured credentials remain authoritative. Failed read authentication can recover once; mutations are never automatically replayed.
  • Refreshed chat and profile model catalogues when opening their pickers and rejected stale choices or receipts. Streaming replies append text without unnecessary full redraws.
  • Kept chat commands, worker controls, Kanban task-body edits and managed-file views tied to their owning session, connection and constructor claim. Accepted busy-input history durability still depends on backend guarantees.
  • Preserved initialized keymaps and customized direct, popup and buffer-local maps during coherent source reload. Incompatible retained transport or event-tail layouts refuse loading before mutation and require a restart.
  • Restored strict Emacs 29.1 checks and markdown-mode 2.6 fence compatibility; bounded reconnect attempts across flapping connections and optional eval requests, and preserved literal recovery after interrupted restoration.
  • Preserved empty prompts when editing skills-only and script-only cron jobs;

… …