Skip to main content

memory-rewind

❖ Communityv1.3.2★ 0

Automatic version history for the built-in memory (MEMORY.md, USER.md), SOUL.md and skills/ (including curator-archived skills): browse, diff and restore any past version with `hermes memory-rewind`, or view it from any chat with the read-only `/memory-history`. Works alongside the built-in memory; not a memory provider.

Open in Hermes Desktop
hermes plugins install memory-rewind

What it adds

Hooks 4

on_session_startpre_llm_callpost_tool_callon_session_end

README

From the reviewed commit 3549271 ↗; it updates when the author re-pins.

memory-rewind

Automatic version history for a Hermes agent's own knowledge — memories/MEMORY.md, memories/USER.md, SOUL.md and the skills/ tree (including curator-archived skills) — with commands to browse, diff and restore any past version.

Hermes rewrites these files while it works: the memory tool edits the memory store, skill_manage creates and edits skills, the curator archives and consolidates them. None of those writes keeps a history, so a truncated MEMORY.md, a skill edited into a broken state, or an archived skill that will not come back has nothing to roll back to. memory-rewind records every change as it happens and lets you put any file or skill back exactly as it was.

Install

hermes plugins install AhmetArif0/hermes-memory-rewind#memory-rewind --enable

Requires Hermes 0.21.5 or newer and git on PATH. Restart a running gateway (hermes gateway restart) so it loads the plugin. History starts with the next session.

Use

hermes memory-rewind log                        # recent versions of everything
hermes memory-rewind log memory                 # versions of memories/MEMORY.md
hermes memory-rewind log skills/research/arxiv  # versions of one skill
hermes memory-rewind show <version> user        # memories/USER.md at a version
hermes memory-rewind diff <version> memory      # what changed since a version
hermes memory-rewind restore <version> memory   # put MEMORY.md back (asks first)
hermes memory-rewind restore <version> skills/research/arxiv --yes
hermes memory-rewind snapshot -m "before cleanup"
hermes memory-rewind status
hermes memory-rewind forget --yes               # delete the whole history

memory, user and soul are shortcuts for memories/MEMORY.md, memories/USER.md and SOUL.md. Versions are the ids printed by log (HEAD, HEAD~1, … also work). Commands act on the active profile (hermes -p <profile> memory-rewind …).

log shows what produced each version:

$ hermes memory-rewind log user
3f2a9c1b7e  2026-09-27 14:05  after memory  (1 file)
    via   memory: remove, add (user)
    from  telegram, session 20260927_140012_ab12cd
    M  memories/USER.md

via names the tool call: the tool, its actions, and the memory target or skill names, with [error] (or [blocked], [timeout], …) when the call did not succeed. from names the session and, when Hermes reported it, the platform.

From a chat

/memory-history shows the same history from any chat: Telegram, Discord and other gateway platforms, the Desktop app, the TUI and the CLI chat. It is read-only.

/memory-history                          the last 10 versions
/memory-history user                     versions of USER.md (also memory, soul, skills/<path>)
/memory-history <version> [target]       what that version changed

Viewing never records a version. Restoring stays a host command; the version view prints the exact hermes memory-rewind restore … line to run. Replies are plain text and at most 3,000 characters, and a reply never includes host paths or raw git errors.

Every restore records the current state first and prints the command that undoes it. Built-in memory is loaded when a session starts, so a restored MEMORY.md/USER.md takes effect in the next session (/new).

What is recorded

Recorded Never recorded
memories/MEMORY.md, memories/USER.md .env, auth.json, keys and certificates, database files
SOUL.md skills/.hub/ (hub lock, audit log, cache, quarantined skills)
skills/**, including skills/.archive/ skills/.usage.json, curator ledger, state and backups, bundled-skill manifest
Hermes lock files (skills/.locks/, skills/.usage.json.lock)
symlinks, embedded git repositories, caches, files larger than max_file_kb

A version is recorded when a session starts and when each turn starts (baselines before anything can change), after each memory or skill_manage call (and file edits that target these paths), and at the end of each turn to catch changes the turn made outside tools (terminal edits). Unchanged state records nothing. Each version notes the tool calls and sessions behind it; the file list shows what actually changed. Changes made between turns, such as a staged write approved with /memory approve, a curator run or an edit in the Desktop app, land in the next session start or turn start version, which names no call or session.

History is a bare git repository at ~/.hermes/plugin-data/memory-rewind/history.git (per profile). It is isolated from your own git setup: your global config, hooks and signing are never used.

Settings

Set in the Desktop Plugins tab, or in config.yaml:

plugins:
  entries:
    memory-rewind:
      settings:
        enabled: true        # record new versions automatically
        track_skills: true   # version skills/ (including .archive)
        track_soul: true     # version SOUL.md
        max_file_kb: 1024    # skip larger files

Security and footprint

  • No network access, no downloads, no self-update, and no Python dependencies (standard library only). The only external program is the local git binary.
  • What it registers: the hooks on_session_start, pre_llm_call, post_tool_call and on_session_end, the hermes memory-rewind command, and one read-only slash command, /memory-history. It gives the model no tools. register() only registers; it does no I/O. The pre_llm_call callback declares only the session id and platform, so Hermes never passes it the user message or the conversation, and it returns nothing, so nothing is added to the prompt.
  • What it reads: memories/MEMORY.md, memories/USER.md, SOUL.md and skills/ (minus the exclusions above), plus its own settings. It never opens .env, auth.json, databases or skills/.hub/. From hook payloads it keeps only the tool name, action names, memory target, skill names, call outcome, session id and platform, never message or file content.
  • What it writes: only $HERMES_HOME/plugin-data/memory-rewind/ (the history repository and an index cache). Tracked files are written only when you run restore, and forget deletes only the history.
  • How git runs: against its own bare repository, with your global and system git config, hooks, signing and pager ignored, literal pathspecs, a 60-second timeout, and background gc detaching disabled.
  • When it runs: a synchronous baseline when a session starts and when each turn starts (about 40 ms once history exists; the very first one records the whole skills tree and took 0.7 s on a 1,100-file tree), and background snapshots after memory/skill_manage calls and at the end of each turn. On exit, a queued snapshot gets up to 5 seconds to finish.

Privacy

History keeps what the files contained. If you ask the agent to forget something, the removal is recorded, but older versions still contain it. Versions also note session ids, platforms and skill names. A /memory-history reply in a group chat is visible to everyone in it, including what a version changed in memory. Run hermes memory-rewind forget --yes to delete the history for the active profile.

Limits

  • External memory providers (Honcho, Mem0, …) store data outside these files and are not covered.
  • Restore is a command you run on the host; the agent has no tool to rewrite history or restore, and /memory-history cannot restore.
  • Snapshots after a call and at turn end run in the background and usually land within a fraction of a second. A change something else makes in that window, or while a turn is running, is recorded with that call or turn.

How it works

See docs/DESIGN.md.

Development

python -m pytest tests/                                   # unit tests (no Hermes needed)
PYTHONPATH=/path/to/hermes-agent python -m pytest tests/  # plus end-to-end tests against Hermes

The end-to-end tests load the plugin through Hermes' real plugin manager, drive the real memory tool and hook dispatch, run the hermes CLI, and check that separate profiles keep separate histories.

Changes

  • 1.3.2: Fix: restore could replace what a running agent had just written. It now applies only the plan it showed: it holds the memory tool's own lock on MEMORY.md or USER.md while it checks and writes, and it refuses when a file changed after the plan was made (for example, a gateway session stored a memory while you read the plan; run the command again to see the new plan). For a memory file the plan also lists the entries the restore brings back and the entries it removes: restoring the file to bring back one deleted entry also removes the entries added after that version.
  • 1.3.1: Fix: importing a Hermes backup (hermes import, also what the dashboard's import runs) put the backup's copy of the history back over the live one. Every version recorded after the backup, including the state right before the import, dropped out of log, and git later deleted it for good. Each version now leaves a small marker, so those versions stay in the history and the import itself is recorded as a change that restore can undo. This protects any import made after 1.3.1 has run once (a session start is enough), whichever version made the backup. The design-notes link on the plugin page works again.
  • 1.3.0: Fix: changes made outside the agent's turns were credited to whatever came next. With memory.write_approval on, a write approved with /memory approve appeared as the agent's next memory call (for example via memory: remove on a version that added an entry), and a skill the curator archived appeared as the next session's work. Each turn now starts with a baseline, and the session-start baseline names no session, so these changes land in a turn start or session start version that names no call or session.
  • 1.2.0: /memory-history shows the history from any chat surface (gateway platforms, Desktop, TUI, CLI chat): recent versions, the versions of one file or skill, and what a version changed. It is read-only and follows the profile of the chat it runs in. Fix: some edits were missed. If an edit kept a file's size and landed in the same second as the previous snapshot, it could go unrecorded, and the newest version then kept the old content.
  • 1.1.0: log shows what produced each version: the tool call (tool, actions, memory target or skill names, and the outcome when it did not succeed) and the session and platform. Hermes' skill lock files and curator/Termux state files are no longer recorded. Before, every skill_manage call added a version holding only a lock file. Older versions that contain them never restore them. After upgrading, the first new version lists them as removed from the history; the files on disk are not touched.
  • 1.0.0: first release.

License

MIT

ntfy-approval❖ Community★ 1

Answer Hermes' approval prompts from your phone: once selected with security.approval.transport: ntfy, each dangerous-command prompt arrives as an ntfy push notification with Approve once, Approve for session and Deny buttons, and no answer still means deny. Disclosure — once selected, anyone who can read the ntfy topic can approve dangerous commands (the one-time answer codes are in the notification), so on the public ntfy.sh default the topic name is the only secret and NTFY_APPROVAL_TOKEN is optional; each pending approval publishes Hermes' reason, the redacted command (unless send_command is false), the non-default profile name and one-time answer codes to the configured ntfy server, then reads <topic>-reply and deletes the notification; any failure or timeout is a deny; reads NTFY_APPROVAL_TOPIC/NTFY_APPROVAL_TOKEN from the profile .env, never puts the token in a notification, follows no redirects, writes no files and starts no processes.

Automation
cloudflare-workers-ai-provider❖ Community★ 0

Cloudflare Workers AI as a Hermes model provider (`--provider workers-ai`, or Cloudflare Workers AI in `hermes model`, which asks for the token and the account's base URL): the 16 Workers AI models with function calling and 64K+ context, Cloudflare's context windows (a custom endpoint lists no models and assumes 256K for the 128K gpt-oss), reasoning effort in the form each model accepts, and a clear message when a free-plan account picks a paid-plan model. Not affiliated with Cloudflare. Disclosure — registers one model provider at import and nothing else (no tools, hooks, commands or threads); the model list and details are built in, so nothing is fetched to show them; chat requests go to the URL in CLOUDFLARE_WORKERS_AI_BASE_URL through Hermes' own client with CLOUDFLARE_WORKERS_AI_API_TOKEN, both read by Hermes per profile; the plugin itself opens no connections, reads and writes no files and starts no processes.

Models
groq-provider❖ Community★ 0

Groq as a Hermes model provider (`--provider groq`, or Groq in `hermes model`): reasoning effort is sent in the form each Groq model accepts, so gpt-oss-120b and gpt-oss-20b work (through a custom endpoint, Hermes 0.21.5 sends them a value Groq rejects with HTTP 400), and the model list leaves out Groq's speech-to-text, text-to-speech, prompt-guard and 4K-context models that Hermes cannot run. Not affiliated with Groq. Disclosure — registers one model provider at import and nothing else (no tools, hooks, commands or threads); chat requests and the model list go to https://api.groq.com/openai/v1 (or the configured model.base_url) through Hermes' own client with GROQ_API_KEY, which Hermes reads; the plugin itself opens no connections, reads and writes no files and starts no processes.

Models
reaction-feedback❖ Community★ 0

Lets the agent see the emoji reactions you leave on its Telegram messages: react 👍 or 👎 to a reply and the agent's next turn in that private chat starts with a short note naming the reaction and the message it followed. Disclosure — registers pre_gateway_dispatch (always returns None, so dispatch is never changed), pre_llm_call and gateway_platform_event hooks; keeps a bounded in-memory record of private-chat message ids, 60-character excerpts and reactions; writes nothing to disk, makes no network requests, starts no processes and reads no secrets.

General

← Back to the catalog · catalog built Oct 8, 2026