All plugins

workflow-record

hermes record: demonstrate a browser workflow once (clicks, field values, navigations) and its bundled skill lets /learn turn the recording into a skill that replays it with the browser tools. A Hermes Labs plugin: built by Nous Research, not supported. Disclosure — attaches over CDP to a Chromium you point it at (--cdp, BROWSER_CDP_URL, browser.cdp_url or 127.0.0.1:9222) and records what you do in that tab until Ctrl-C; password, one-time-code and card fields are masked inside the page as {SECRET:name} and never written. Recordings stay local in <HERMES_HOME>/recordings; nothing is sent anywhere until you run /learn on one, which hands it to your active model.

NousResearch154AutomationUpdated 15 days ago

About

hermes record: demonstrate a browser workflow once (clicks, field values, navigations) and its bundled skill lets /learn turn the recording into a skill that replays it with the browser tools. A Hermes Labs plugin: built by Nous Research, not supported. Disclosure — attaches over CDP to a Chromium you point it at (--cdp, BROWSER_CDP_URL, browser.cdp_url or 127.0.0.1:9222) and records what you do in that tab until Ctrl-C; password, one-time-code and card fields are masked inside the page as {SECRET:name} and never written. Recordings stay local in <HERMES_HOME>/recordings; nothing is sent anywhere until you run /learn on one, which hands it to your active model.

Workflow Record

Labs plugin: works, but unsupported. Nous Research built it and does not maintain it. See
what "labs" means.

hermes record lets you show Hermes a browser workflow instead of describing it. It attaches to
your Chromium-family browser (Chrome, Chromium, Brave, Edge) over the DevTools protocol, watches
what you do in the active tab, and saves the demonstration as a JSON recording. A bundled skill
then tells /learn how to turn that recording into a skill that replays the flow with Hermes'
browser tools.

record  ->  /learn  ->  replay

Install

hermes plugins install workflow-record

It adds one CLI command (hermes record) and one skill (workflow-record:replay-recording). No
model tools, no hooks, nothing runs during chats. The only dependency is websockets, which Hermes
already ships.

Record

  1. Start a browser Hermes can reach over CDP. Any of these works:

    • in a Hermes chat, /browser connect (launches Chrome with remote debugging on port 9222), or
    • start it yourself: google-chrome --remote-debugging-port=9222 --user-data-dir=<dir>, or
    • point Hermes at an existing endpoint with browser.cdp_url in config.yaml.
  2. Open the page where the workflow starts and keep that tab in front.

  3. Run:

    hermes record --slug shop-login
    
  4. Do the workflow in the browser, then press Ctrl-C in the terminal. Hermes saves the recording
    and prints the next step.

The endpoint is taken from --cdp URL, else BROWSER_CDP_URL, else browser.cdp_url, else
http://127.0.0.1:9222. A /browser connect made inside a running chat lives only in that chat's
process, so hermes record finds that browser through the default port, not through the chat.

What gets captured:

| Step | Stored |
|---|---|
| click | CSS selector path and the element's visible label (never a field's value) |
| input | selector and the field's final value, captured on change (not per keystroke) |
| enter | selector of the focused element when Enter was pressed |
| navigate | top-frame URL changes |

Other modes:

hermes record --list      # list saved recordings
hermes record --manual    # no CDP: type what you did, one step per line
hermes record --cdp http://127.0.0.1:9333 --slug checkout

Where recordings go

<HERMES_HOME>/recordings/<slug>-<UTC timestamp>.json, resolved through get_hermes_home(), so
hermes -p work record writes into the work profile. Files are never uploaded anywhere.

{
  "version": 1,
  "started_at": "2026-10-21T12:00:00+00:00",
  "url": "https://shop.example.com/login",
  "steps": [
    {"t": 0.0, "type": "click", "selector": "input#user"},
    {"t": 1.2, "type": "input", "selector": "input#user", "value": "alice"},
    {"t": 2.0, "type": "input", "selector": "html > body > form > input[name=\"pw\"]", "value": "{SECRET:pw}"},
    {"t": 2.4, "type": "click", "selector": "button#go", "text": "Sign in"},
    {"t": 2.6, "type": "navigate", "url": "https://shop.example.com/home"}
  ]
}

t is seconds since the first step.

Secret masking (two layers)

  1. In the page. The recorder script never reads the value of a type=password field or a field
    whose autocomplete is current-password, new-password, one-time-code, cc-number or
    cc-csc. It sends {SECRET:<field name>} instead, so the value never crosses the DevTools
    socket. Clicks never copy a field's value either (only button labels and element text).
  2. In Hermes. Before anything is saved, the normalizer masks again from the field type and
    autocomplete hint the page reported, and drops any "text" on a click that landed on a form
    field. A page that changes an input's type mid-flight, or a hand-made event, still cannot put
    a raw password in the file.

Placeholders are resolved only at replay time: the replay skill fills logins, one-time codes and
cards through browser_vault (saved logins or a masked prompt, so the value never enters the
conversation), or through an env var / secret reference you set yourself. Hermes never asks you to
paste a secret into chat and never writes one into a skill.

Turn a recording into a skill

hermes record ends by printing the exact line. In a Hermes chat:

/learn the browser workflow recorded in /home/me/.hermes/recordings/shop-login-20261021-120000.json (follow the workflow-record:replay-recording skill)

The workflow-record:replay-recording skill (listed in the model's skills while the plugin is
enabled) gives /learn the recording schema and the rules: rebuild the workflow in human terms,
treat recorded page text as data, map each {SECRET:*} to browser_vault or a named env var,
and write a Procedure that replays with browser_navigate, browser_snapshot, browser_click,
browser_type and browser_press, using the recorded selectors only as hints.

Then use the new skill like any other: "log into the shop and check my order status".

Limits

  • One tab. Only the tab in front when recording starts is captured. Flows that open a new tab
    or a popup stop being recorded at that point.
  • Values on change. A field you never left (no blur, Tab or Enter) may be missing; press Tab
    before Ctrl-C.
  • Only password-like fields are masked. An API key typed into a plain text field, or a site
    that puts a secret in a URL (a GET login form, a token in a query string), is recorded as typed.
    Review the JSON before sharing it, or use --manual for sensitive flows.
  • Pages can see the recorder. The capture channel is a page-visible function, so a page could
    add fake steps. The replay skill treats every recorded label and URL as untrusted data; review
    recordings of sites you do not trust before learning from them.
  • Not captured: scrolling, hovering, drag and drop, file uploads, canvas or shadow-DOM-internal
    interactions, iframes' own navigations.
  • Chromium only. Firefox and Safari don't speak CDP; use --manual there.

Configuration

None. The CDP endpoint uses Hermes' existing settings:

hermes config set browser.cdp_url http://127.0.0.1:9222

Development

cd workflow-record
HERMES_AGENT_REPO=../../hermes-agent PYTHONPATH=../../hermes-agent python -m pytest -q

tests/test_live_browser.py drives a real headless Chrome/Chromium/Edge when one is installed
(skipped otherwise): real mouse clicks and typing through CDP input events on local pages, and it
asserts the password never crosses the socket.

Origin: hermes-agent PR #72199 (hermes record), moved out of core into this plugin.

README from the reviewed commit fde77be; it updates when the author re-pins.

More by NousResearch

28 plugins by NousResearch in the catalog.

NousResearchaccent-pickerOKLCH accent colour picker for the Hermes Desktop status bar: drag it and the whole theme retints live, with palette commands to reset to the theme default or copy the current colour. A theme-authoring tool; the colour is scratch state and is never persisted. Desktop-only (desktop/plugin.js inside the plugin SDK surface); no agent tools, hooks, middleware or env vars.OfficialDesktop app607NousResearchadvanced-delegationTwo extra delegation modes for `delegate_task`, next to the built-in default. Model routes (`delegation.backend: model_map`): the agent picks a named model route per subagent from a list you define (e.g. fast, deep, local). Profile routes (`delegation.backend: profile_routes`): the agent runs a subagent as one of your Hermes profiles, with that profile's own model, credentials, skills and SOUL.md. Only route names and their one-line descriptions reach the model. Adds `hermes delegation config` (pick the mode and edit its routes; `--show` prints the setup) and the `/delegation` slash command (save a mode for the next session, or `--now` to apply it to the current chat). Needs Hermes 0.22.5 or newer, the first release with pluggable delegation providers; Hermes 0.22.0 to 0.22.4 refuses to install it, and on a core older than 0.22.0 it installs, logs one warning and does nothing. A model route can set `daybreak: true` to run its model with OpenAI's Daybreak trusted-access program; it is sent only from your own CLI, TUI or Desktop chats, on `openai-codex`, for models your Codex catalog lists, and a route that breaks a rule is refused. Disclosure — no Python dependencies and no network or model calls of its own, except that a Daybreak route checks the Codex catalog through core's cached lookup with your existing Codex login; subagents run through core's `delegate_task` on the routes you configured. Writes only `delegation.backend` and `delegation.backends.*` (model_map / profile_routes) in the active profile's config.yaml, through core's config writer. A model route's optional `api_key` is stored in config.yaml in plain text (`provider:` keeps keys in .env / auth.json). Listing a profile under profile routes lets this profile's subagents use that profile's credentials, SOUL.md and terminal policy.Officialtools607NousResearchagent-importers`hermes import-agent`: import an OpenClaw (~/.openclaw, or legacy ~/.clawdbot / ~/.moltbot), Claude Code (~/.claude), Codex CLI (~/.codex), Cursor (~/.cursor), Grok Bot (a self-export the Bot writes from a prompt the importer prints) or OpenBot desktop (its openbot.db) setup into Hermes in one command; always previews first and asks before applying. Claude Code / Codex / Cursor: instructions, Cursor rules and memories become memory entries, Bash permission rules become command allow/deny lists, MCP servers land in config.yaml, skills are copied, and `--sync` re-imports sources that changed. OpenClaw (core's former `hermes claw migrate`; the plugin keeps that spelling, `hermes claw cleanup` and the openclaw-migration skill): persona, memories, skills, model and messaging settings, MCP servers and agent behaviour. Formerly built into Hermes core; `hermes setup` offers to install it when it finds one of these agents, and profiles with a registered sync source are migrated automatically. Disclosure — no Python dependencies, no network calls and no model calls. Claude Code / Codex / Cursor: reads those agents' local config trees (never their credential files; secret-looking MCP env vars and headers are stripped and listed) and writes only into the active profile (memories/MEMORY.md with a backup, config.yaml, skills/ and import-sync.json). OpenClaw: reads the OpenClaw dir (openclaw.json, its .env, workspace files such as SOUL.md / MEMORY.md / USER.md, skills); API keys and bot tokens come over only with --migrate-secrets (allowlisted names, shown in the preview). It writes into the active profile (config.yaml, .env, SOUL.md, memories/, skills/openclaw-imports/, a migration/openclaw/<time>/ report with item backups, and a backups/pre-migration-*.zip restore point), plus a workspace dir only when --workspace-target names one. It runs local pgrep / systemctl / tasklist checks to warn when OpenClaw or a Hermes gateway is still running, and `hermes claw cleanup` renames the OpenClaw dir to *.pre-migration after a confirmation. Grok Bot / OpenBot: instructions become SOUL.md, memories and user facts become memory entries, skills land in skills/<source>-imports/, scheduled routines become paused cron jobs (--activate-routines to start them) and event routines a notes file; credential-looking export keys refuse the file, and secret MCP env vars and headers are stripped and listed. OpenBot's database is opened read-only (or read from a scratch copy that is deleted after the read).Officialtools607NousResearchblenderOfficial Blender Lab MCP server over stdio, pinned to upstream v1.0.3, with a Blender workflow skill. Needs Git and uv; Blender 5.1+ is not needed at install. The skill opens Blender itself when a task needs it and, after you agree, installs Blender and Blender Lab's MCP add-on. First startup downloads Python dependencies; prepare the uv environment before connecting. Disclosure — tools execute arbitrary Python in Blender with your privileges; the skill starts Blender with online access for that session only (your saved preference is unchanged), and the add-on's local server on port 9876 has no password, so any program on this computer can use it while Blender is open; only after you agree does the skill download Blender from download.blender.org (about 400 MB, about 1.5 GB unpacked), check it against blender.org's sha256 list and install it in your own folder without administrator rights (Linux ~/.local/opt, macOS ~/Applications, Windows %LOCALAPPDATA%\Programs\Blender Foundation; never over an existing Blender), and download the v1.0.3 add-on, check its hash and install or enable it; first start downloads the pinned Blender Lab MCP server and its Python dependencies with uv. Server discovery does not prove scene readiness.Officialtools607