All plugins

helper

Desktop page for people who are new to Hermes: a Dashboard with nine set-up cards (what each thing is, the steps from the Hermes docs, a button to its place in Hermes) and Helper, a small character with its own conversation window that answers questions about Hermes in plain words, from lines checked against the Hermes docs. Disclosure — reads, through Hermes's read-only Desktop calls, whether a model is ready and its name, the list of profiles and each profile's skills, the connected chat apps, and the main profile's chat list (with previews, only to tell whether a first chat exists); in Helper's set-up conversation it also reads the main profile's SOUL.md text and the list of scheduled jobs; never reads .env, auth.json or config files. When its fixed rules are not sure of an answer it sends the typed message, the last few lines of the Helper conversation and chunks of the Hermes docs to the person's own configured model (llm.oneshot), and once per set-up conversation it sends a fixed "Reply with exactly: OK" check when a model is set; both spend their model credit; no tools run and nothing is saved to their chats. Keeps a name, a few answers, the Done marks and the last 50 lines of the Helper conversation as plain text in Desktop plugin storage, shared by all profiles on the computer and not removed on uninstall. Only when the person presses its buttons, 'Do it for me' runs Hermes's own importer (hermes import-agent <agent> --dry-run, then hermes import-agent <agent> --yes, for Claude Code, Codex, Cursor or OpenClaw only) and, if the importer is missing and the person agrees, hermes plugins install agent-importers --enable; no other command can run and the model cannot write one. No network calls of its own, no telemetry, no self-update. Desktop-only (desktop/plugin.js, no __init__.py): no agent tools, hooks, middleware or env vars.

benhensDesktopv0.1.0Updated 7 hours ago

About

Desktop page for people who are new to Hermes: a Dashboard with nine set-up cards (what each thing is, the steps from the Hermes docs, a button to its place in Hermes) and Helper, a small character with its own conversation window that answers questions about Hermes in plain words, from lines checked against the Hermes docs. Disclosure — reads, through Hermes's read-only Desktop calls, whether a model is ready and its name, the list of profiles and each profile's skills, the connected chat apps, and the main profile's chat list (with previews, only to tell whether a first chat exists); in Helper's set-up conversation it also reads the main profile's SOUL.md text and the list of scheduled jobs; never reads .env, auth.json or config files. When its fixed rules are not sure of an answer it sends the typed message, the last few lines of the Helper conversation and chunks of the Hermes docs to the person's own configured model (llm.oneshot), and once per set-up conversation it sends a fixed "Reply with exactly: OK" check when a model is set; both spend their model credit; no tools run and nothing is saved to their chats. Keeps a name, a few answers, the Done marks and the last 50 lines of the Helper conversation as plain text in Desktop plugin storage, shared by all profiles on the computer and not removed on uninstall. Only when the person presses its buttons, 'Do it for me' runs Hermes's own importer (hermes import-agent <agent> --dry-run, then hermes import-agent <agent> --yes, for Claude Code, Codex, Cursor or OpenClaw only) and, if the importer is missing and the person agrees, hermes plugins install agent-importers --enable; no other command can run and the model cannot write one. No network calls of its own, no telemetry, no self-update. Desktop-only (desktop/plugin.js, no __init__.py): no agent tools, hooks, middleware or env vars.

Helper

A Hermes Desktop plugin that helps you understand Hermes and set it up the way you want, one step at a time. It explains and checks; it never installs, builds or changes settings for you.

Status: early build (the Dashboard, Helper's conversation window and Helper's page in Settings). Helper's conversation answers many messages from pre-written lines chosen by fixed rules on your computer. When those rules are not sure, the AI your Hermes uses writes the reply from Helper's checked lines, and fixed rules check it before it is shown (point 11).

What it adds

  • One row in Hermes's left sidebar: Helper.
  • One page, the Dashboard (no tabs: Learn and My setup are out).
  • Dashboard: at the top, three tiles, each with the icon Hermes itself uses for that thing: the number of bots and of skills (different skill names across all your bots) for your whole Hermes, and Plugins (no number; it opens Hermes's own Plugins screen). The word follows the number ("1 bot", "2 bots"); each number shows a grey block until it is read, and a number that cannot be read is not shown. Under each tile one plain line says what the thing is ("Each bot is a separate Hermes.", "Each skill teaches Hermes one task.", "Each plugin is an add-on for Hermes."). Right under the tiles, Set up with its count ("0 of 9") over 9 cards in the order of the Hermes docs: A model, First chat, Its personality, Chat apps, Tools and apps, Skills, Memory, A second bot, Safety. Each card shows Hermes's own icon, its name and one sentence that says what it is. Nothing is read to decide what is done: a card is done only when you press its Done button, and then it says "Done" and the count goes up (press Not done yet to take it back). Your marks are kept with what Helper keeps (they show on Helper's page in Settings and go with "Forget all of this"). The first card not marked says "Start here". A click on a card opens it full width under its row (one at a time; click again or the close button to close it): first a place for a short video ("Video coming soon" until it has one), then the numbered steps, the docs file and line they come from, any text the docs give to paste (with Copy), and for three cards a button that opens that place in Hermes (Model settings, a new chat, Messaging). An opened card stays open when you come back from that place. Videos, once added (content/videos.json), load from the web, and only when you press Play. The Dashboard makes no AI call, changes nothing in your Hermes and stores nothing about your bots (only your Done marks): it reads the numbers again each time you open it.
  • The first build's tabs, Setup (four steps) and Your setup (seven cards), are no longer on the page; their code is kept in src/ but not in the built file (see "For developers").
  • Helper's conversation window on the right. Its character sits on the top edge of the message box: two eyes and a mouth in the theme's accent colour, holding on with its fingers. It comes up from behind the box when the page opens, its eyes follow your cursor while it is over this page (or the field the keyboard is on), and it shows when it is busy, asking or talking. Helper's newest sentence is in a speech bubble above the character and appears word by word; press a key or the mouse to see the rest at once. When Helper asks your AI, three dots show in the speech bubble while it waits, for at most 12 seconds. If your AI is slow, not set up, or its reply fails Helper's checks, Helper shows its own pre-written line instead. If your AI is too slow or fails twice in a row, Helper stops asking it for the rest of the visit. When it was too slow, Helper says so once, right after its own answer, with a text you can paste into your own Hermes to make it quicker. Otherwise it says nothing about it. Older lines move up as small bubbles, your own messages are on the right, and the conversation scrolls when it is full. Only some questions come with answers to pick (which AI, which chat app, which service, "which one do you mean?", and Yes / No before deleting): they appear inside the message box, above the line where you type, once Helper's line is said, and go away when you pick one or send a message; you can always type instead. Ask "what can I ask?" to see the four topics. Some lines hold a button: one opens a text to paste into a chat with your own Hermes, one opens Hermes's own Messaging, Model or Capabilities screen. If you ask Helper to do something for you (install, connect, set up), it gives you a text to paste into a new chat with your own Hermes instead, because Helper never changes anything itself. With your system's "reduce motion" setting on, the character stays still, each line appears whole and the answers appear at once.
  • What Helper keeps about you (your name, three kinds of answers, up to three things you ask it to remember): each time it keeps something, a small line says so ("Kept: ...") with a "See what I keep" link; your name is kept as soon as you give it. Helper asks your name only on your very first visit: after that, also when you pressed Skip, it opens with "Hi again" (by name when one is kept) and asks nothing; type "my name is ..." to change the name. "Forget all of this" (in Settings, or typed as "forget everything" and Yes) is a full reset: it also removes the mark that Helper has said hello, so the next time Hermes opens Helper greets you as on a first visit and asks your name again. Ordinary talk gets ordinary lines: "hey", "thanks", "ok", or a message that looks cut off ("he") never gets the "I don't know" line, and Helper never says the same line twice in a row. Say "my chat app is WhatsApp" (or the AI or service you use) and the newest replaces the one kept. Type "what do you know about me" to see the list, or "forget my name" (it asks Yes or No first). Once something is forgotten or replaced, its older "Kept: ..." line is struck through.
  • Using fewer tokens: ask in your own words ("how can I use less usage?") and Helper says long chats use the most and where "New session" is; its button "See what uses them" says to type /usage in a Hermes chat.
  • Helper's own page in Hermes's Settings (Settings, then Plugins, then Helper): what Helper keeps, as a short text you can edit, one thing per line. Save reads it back by fixed rules and asks before it forgets anything; "Forget all of this" deletes it all.
  • What Hermes can do, checked against its docs: "What Hermes can do" shows four picks; "Web, files, pictures and voice" asks what you want Hermes to do, with four groups (Search and use the web, Files and my computer, Pictures and video, Voice and sound), and a group shows what Helper has checked for it: 26 things in all, three at a time with "More" when there are more than four. Each says what Hermes has for it (a built-in tool, a skill that comes with Hermes, or an optional skill you add first) and gives a text to ask your own Hermes, or, for an optional skill, the clicks in the Hermes app to add it. Typed questions reach them too ("can it read PDFs"). Ask about a skill by its name next to the word "skill" ("is there a github skill", "what does the dspy skill do") and Helper says whether Hermes comes with it or you add it first and, in plain words, what it teaches Hermes (174 of the 186 skills; the other 12 keep a fixed sentence), with the official docs' own description in a box headed "From the Hermes docs". A skill name that is also an ordinary word (shop, maps, sketch, 19 in all) counts after "skill for" only as the last word ("is there a skill for shop", not "skills for shop owners"). Asked "is there a skill for knitting", Helper says it does not know rather than explaining what a skill is. Where nothing is checked but the question is close to a group, Helper says it does not know and offers that group's nearest things. Gmail gets the way to the app's Connectors page, and Google Calendar and Google Drive how to look for themselves there; GitHub gets the github skill. Asked to build something ("make me a website"), or whether Hermes can ("can it build a website?"), Helper gives the text to paste into your own Hermes. Two-word names win over their single words ("google drive", "google mail", "one drive" is OneDrive), also when typed as the answer to "Which service?". Every docs line Helper's checked answers quote is checked against the Hermes v0.23.0 docs when the plugin is built.
  • Drag the window's left edge to make it between 360 and 600 px wide (or use the arrow keys on it); the width is remembered.
  • Narrow windows: Helper's window narrows so the open tab keeps 320 px (to about 408 px at the least), and the Dashboard takes smaller sizes when its side is under 640 px wide. When the page is too narrow for both sides, Helper lies over the page with a thin strip at the page's right edge; press the strip (or Escape) to fold Helper away, and the strip again to bring it back.

What it reads, sends and changes

  • Reads your Hermes setup only through Hermes's own read-only calls: whether a model is ready and its name (setup.runtime_check, setup.status, free_tier.status), and for the Dashboard only your bots (profiles.list) and each bot's skills (host.skills.list), for its numbers; the Dashboard reads nothing to decide what is set up. Helper's set-up conversation (in this build) looks at what is set up when it starts: your bots (profiles.list), and for your main bot whether a model answers (setup.runtime_check), its SOUL.md text (profiles.describe) and its scheduled jobs (cron.manage list). It never reads .env, auth.json or your config file.
  • The "The model answers" card makes one call to your own model through Hermes, and only when you press Check. It asks the model to reply "OK", which spends a little of your model credit. Helper's conversation also calls your own model through Hermes, one or two short calls for a message its fixed rules are not sure of (point 11). These calls spend a little of your model credit too. Nothing is saved to your chats and no tools run.
  • Changes nothing in your setup on its own. Where it suggests something, it gives you the steps or a text to paste; you decide and do it. The Dashboard's buttons only open a place in Hermes (or a new chat). One exception, and only when you press its buttons: "Do it for me" under a reply in Helper's window runs Hermes's own importer for a setup from Claude Code, Codex, Cursor or OpenClaw (Hermes's cli.exec). The first press runs only a preview (hermes import-agent <agent> --dry-run, which changes nothing); a second press, "Import it", runs the import (hermes import-agent <agent> --yes). If your Hermes lacks its import add-on, Helper asks first and "Install it" runs hermes plugins install agent-importers --enable. These are the only commands it can run; the AI cannot write a command.
  • Makes no network calls of its own: no telemetry, no server, no self-update. A source tag on the Dashboard (a docs file and line) opens that official docs page in your web browser when you press it.
  • Never sends a pasted API key anywhere: the message box checks for one first and shows where keys belong instead. The key is not shown back and not kept.

What Helper keeps, and where it goes

  1. Helper keeps a few things about you without asking first. It tells you each time, in its conversation.
  2. It keeps your name, if you give it, and what you do (one short answer).
  3. It keeps three kinds of answers you give it: whether you pay for an AI or want a free one, which chat app you use, and one service you named, such as Gmail.
  4. It keeps up to three things you ask it to remember. It only shows them to you. It does not act on them, and they are not sent to any AI.
  5. It keeps nothing else you type. It tries to refuse passwords, keys and long numbers by fixed rules, but it can miss some. Never type a password or key to Helper.
  6. It also keeps a few page settings, such as how wide its panel is, and your answers on its page. It keeps one mark that it has said hello, so it never asks your name twice. Besides, it keeps the last 50 lines of your conversation with Helper, so they are still there the next time you open Hermes: on this computer, shared by all your bots, and other plugins can read them. It does not keep a line its rules take for a password or key, and kept lines are never sent to any AI. "Clear chat" at the top of Helper's window removes them, and so does "Forget all of this".
  7. These are kept as plain text in the Hermes Desktop app's own storage, on this computer only.
  8. They are shared by all your Hermes profiles (bots) on this computer.
  9. They are not removed when you uninstall Helper.
  10. To see and delete what Helper keeps, press "See what I keep" in its conversation, or type "what do you know about me". You can also open Settings, then Plugins, then Helper.
  11. Helper answers many messages with fixed text, picked by fixed rules on this computer. When those rules are not sure, your message, the last few lines of your talk with Helper and a few of Helper's checked lines are sent to the AI your Hermes uses: the company whose AI you chose, or the AI on your own computer. Your chats with Hermes go there the same way. That AI writes Helper's reply in its own words from those checked lines, and Helper checks each reply by fixed rules before showing it. On a small AI on your own computer, Helper can still say things that are not true, and the checks do not catch all of them. Nothing is sent anywhere else. Of what Helper keeps about you, only what you do is sent, as one short line; your name and the rest never are. Deleting does not take back what was already sent.
  12. Helper has no server of its own. Nothing is sent to its makers.

Install

Needs Hermes v0.23.0 or newer. Any one of these:

  • In Hermes Desktop: open the link hermes://plugin/install?repo=benhens/hermes-helper&enable=1.
  • In a terminal: hermes plugins install benhens/hermes-helper --enable
  • Once the plugin catalog lists it: hermes plugins install helper

Then restart Hermes Desktop: Helper is a row in the left sidebar.

Remove

Capabilities → Plugins → Helper → remove.

For developers

  • src/ holds the readable sources; node scripts/build.mjs joins them into desktop/plugin.js, the one file Hermes loads. Edit src/, then build.
  • The docs data (src/docs-data.js, made by scripts/docs-data.mjs): the built file carries chunks of the Hermes docs as text, and where that text quotes code such as eval( or <script it is written with unicode escapes, so Hermes's plugin lint reads the plugin's code and not the quoted documentation; the plugin's own code has none of these (tests/lint-surface.test.mjs runs the lint's patterns over the built file).
    • The Dashboard (dash-v1, fixes in dash-v2). Two files of the content team's, each copied as it is: content/dash-setup-list-v2.json (the 11 things with their steps) and content/dash-words-v1.json (every other word on the tab, page_words). The build joins them and checks them (scripts/dash-data.mjs: every docs quote on its line of content/dash-docs-lines-v0.23.0.json, cut from the Hermes v0.23.0 docs by dev/checks/dash-v2/docs-lines.mjs; the 11 things; exactly the six counted ones the code has rules for; every word, with the number written in "All 6 are set up." equal to the number counted; route buttons only to the places hhtech ran) and writes src/dash-data.js. src/setup-reads.js: the six rules, one copy for the Dashboard and the set-up conversation. src/dash-rules.js: the path, the days of Activity and the numbers (pure code). In src/dash.css the corners of the cards, tiles, the opened stop's panel, the icon squares and the waiting blocks all come from one value, --hhd-round (1 = today's round look; 0.2 would be Hermes's own corners). src/dash.js: the reads and the tab on screen, with the table of Hermes's own icons (DASH_ICONS, each with the Hermes file and line that shows it). src/dash.css: the tab's style sheet (hhdesign's dash-r7 values; classes hhd-, table D in src/look.js), built into src/dash-css.js and put in a <style> element inside the tab.
    • Parked (dash-v1): src/setup-cards.js, src/setup-tab.js, src/steps.js and src/steps-data.js (the first build's Your setup cards and step list) stay in src/ with their unit tests but are not joined into desktop/plugin.js (PARKED in scripts/build.mjs); their page tests are kept in tests/parked/, out of the run.
    • src/model-call.js: the one way the page asks your model (llm.oneshot, task helping_hand, 90 s) and the fixed line for each way it can fail.
    • src/key-check.js: stops a pasted API key before anything goes to a model.
    • Helper's AI step (talk-live). src/ai-mode.js holds the one switch AI_MODE: no_ai_step (nothing typed is ever sent), ai_picks_line (the person's own AI picks one of Helper's checked lines) or ai_writes (this build, talk-live-2: it writes the reply from those lines, and fixed checks decide whether it is shown). The build prints a note when the content team's data still says another mode, and writes README's four lines that depend on it. content/helper-talk-live-v2.json (the content team's) becomes src/live-data.js; src/live-rows.js holds Helper's checked lines as rows and hands over at most 5 of them (find-v1: when code is not sure of a line, one first call, the list call, hands the AI the list of all 189 fact lines as id = title, Helper's own text and the same for every person, with the usual input, and takes up to three ids, NONE or BUILD in at most 30 tokens; the lines picked go to the writer, each with its next line (find-v2: when the writer then says NONE, fails, is slow, or a check drops its reply, the first picked line itself is shown, as code shows it, with its button; only with nothing picked the don't-know with its picks); a follow-up skips the list call and hands the lines of the answer before; the list call took the place of word matching and of the first call that picked a subject word; a line code is sure of, and anything picked or pressed, never goes to the AI), src/live-request.js makes what is sent (of what Helper keeps only what you do, as one line in the instructions and only when it passes the keep rule again; never the name), src/live-checks.js reads the reply: no_reply first on every call (thinking text is no reply; live-v2 changes-5's lists), then the checks c0 to c24, c26 and c27 (c25 is in the data with adopted: false and is not built), src/live-turn.js runs one message (code first; the AI only when code is not sure), and src/page.js waits at most 12 seconds, with at most one of Helper's calls in Hermes at a time; a message whose try at the AI was slow (no answer in 12 seconds, thinking text) or failed (the call gave an error) is one failed try, and gets Helper's own written line; a message the AI answers in time puts the count back to 0; two failed tries in a row owe the slow-AI line but no longer turn the AI step off (last-reset, Lead 11 Nov; before, they did); one call of Helper's still in Hermes past its 12 s does not hold the next message back, two do. When the second of them was slow, Helper says the slow-AI line SLOW_A once, with a text to paste: right after that written answer; between a don't-know and its picks; after a line with answers to pick, which then stay under it (find-v2). Never after a goodbye, "something is stuck", a question with nothing to pick, or a line with its own text to paste: then it is not said at all. Kept for the visit only, never stored. After a try that failed, and at a message that could not be asked because no model was found, the page asks Hermes again whether a model is there (setup.runtime_check, no model call), so a model that was switched on meanwhile is used from the next message.
    • Offers (setup-chat, the content team's changes-6 to -10). A line of Helper's that would leave you to think of what to type carries an offer instead: a second speech bubble with a question and two to four things to pick in the message box (offers in content/helper-talk-v2.json; attachOffer and pressOffer in src/talk.js; never the same offer twice in a row; typing still works). src/setup-built.js holds the switch SETUP_BUILT (true in this build): while it is false the set-up conversation is not in the build and no offer shows the pick "Set up Hermes". New checks on a reply the AI wrote: c28 (it ends on an invitation or a question) and c29 (what you do used as a step or as a fact about Hermes); the label USED: is read in any case, and a reply with nothing but the label is no reply. A button or pick you press is shown as your message but is never sent to your AI as your words. A call to your AI that fails turns the AI step off until Hermes starts again.
    • The set-up conversation (setup-chat). After "What do you do?" Helper asks two questions (are you new, what do you want), looks at what is set up, recommends one thing, gives its steps one at a time, and goes on from there the next time Hermes starts. Every word is the content team's: content/helper-setup-chat-v1.json (the questions, the lines, the rule) and content/dash-setup-list-v2.json (the things, their names and steps) are checked by the build (scripts/setup-data.mjs) and become src/setup-data.js. src/setup-chat.js holds the fixed rules (pure code): which thing comes next (R1 to R5, tested on all 24576 cases of the team's reference), the typed answers, the steps, what is kept (four more values in the one stored record: new to Hermes, what you want, the things you said are done, the thing recommended last). src/setup-look.js is the look: it reads the list of bots, then for the main bot only whether a model answers (setup.runtime_check), its personality text (profiles.describe) and its scheduled jobs (cron.manage with action: 'list'), each read given up after 8 seconds; a read that fails is said as "I couldn't", never guessed. Nothing is written to Hermes. Since loom-fixes-2, when the settings say a model is set, the look makes one small check call per visit (a fixed "Reply with exactly: OK", nothing of yours in it, at most 12 seconds), so Helper can say whether your model answered ("it answered my check", "it did not answer my check in time", or "no model set up yet" when the call fails for want of one); with no model set, in a build with no AI step, or with the AI off for the visit, it makes none. While a set-up question or step is open, only one question of Helper's is on screen: a typed message is answered with no offer and the open question comes once more, every time (helper-loom-fixes-v2); "go back" goes to the question or step before. src/setup-reads.js turns the answers into done or not done (the Dashboard job's rules). In this build the set-up conversation asks no AI at all: SETUP_AI_BUILT in src/setup-built.js is false (setup-chat-2: on a real free AI 2 of 9 sentences promised things nobody had checked, and a small AI on the computer gave none that could be shown), so every recommendation is the written sentence, at once. A question typed while a step is open is answered, then the step comes back ("Back to step 2 of 5: ...") with its own answers. On a later visit Helper says where you stopped and what the thing is, and first names a thing it can now see done ("I can see you have 1 scheduled job."); "I've done this already" on a thing Helper can see is read again first ("I can't see that yet. ...", with "Count it as done"). With the switch on, src/setup-rec.js asks your AI for the sentence of a recommendation only (only where the AI writes replies). It is handed what you do, what you want, whether you are new, what the look saw, the thing and the written reason; never your name or the steps. Its reply is shown only when it passes the fixed checks (it names the thing and no other, no steps, no question, at most 35 words and two sentences, no promise to do it for you, no numbers); otherwise the written sentence shows. Helper's settings page lists the four kept rows, each with Delete, and the button "Ask me the set-up questions again". The tests in tests/setup/ run on the files as committed; the older tests run with the set-up conversation switched off (scripts/test-modes.mjs).
    • content/steps-v1.json (parked): the step texts, written by the Helper content team; the build still turns it into src/steps-data.js for the parked src/steps.js and its tests.
    • Helper's conversation. content/helper-talk-v2.json: every line Helper can say, its key words, its answers to pick and what it keeps, written by the content team. The build checks it (scripts/talk-data.mjs: every line has a source and keeps the word limits, every answer gives a row of its own topic, no list of things to pick is longer than four, answers only under the questions the team marked in answers.when_shown; with a problem the build stops and writes nothing) and turns the fields the code uses into src/talk-data.js. content/helper-wants-v1.json: what a person may want Hermes to do (24 checked rows in four groups) and the 186 skills of the two official skills pages, written by the content team; the build checks it again (scripts/wants-data.mjs: every line within the word limits, every quoted docs line on its named line of content/docs-lines-v0.23.0.json, the lines of the Hermes v0.23.0 docs it names, cut by the team's dev/checks/talk-v2-wants/docs-lines.mjs; built in or optional as the page says; no command in an optional skill's box; at most four groups of at most eight) and writes src/wants-data.js. src/talk.js: the fixed order of steps that picks a line, a port of the content team's route2.py (a pasted key first, then "remember that ...", "what do you know about me" and "forget ...", "what can I ask", a request to do something, the opening, a skill by its name, then (changes-11) a name typed on a later visit, "what is ..." with the explanation, the cost and where-to-run lines, then key words, the wants' rows, the near miss; the wants steps follow the team's tested order, hhtech's wants_step.py with fixes6_step.py; one change of the Builder's: a wants row wins over the cost and where lines, as a topic word does). src/kept.js: the one stored record of what Helper keeps (key kept), cleaned whenever it is read. src/settings-file.js: Helper's settings page read back by fixed rules, a port of the content team's settings_read.py. src/settings-page.js: that page. src/talk-view.js: the window's parts, and the things to pick in the message box. src/bubble-link.js: the piece between the bubble and the character, one small file so its shape can be swapped. src/layout.js: how the page fits its window.
    • src/talk.css: the one style sheet of the plugin's own, for Helper's window only. Every class starts with hh-, every colour is a Hermes variable, and it has no fonts and no shadows. The build turns it into src/talk-css.js; the page puts it in a <style> element inside its own page, so it leaves with the page.
    • The character, drawn by the page itself as inline SVG shapes in the accent colour (no picture file): src/expressions.js holds the numbers of its four expressions (resting, busy, asking, talking) and the rule for which one shows; src/character.js draws it and moves it; src/eyes.js turns the pupils toward the cursor or the focused field; src/reveal.js shows Helper's lines word by word (WORD_MS, 120 ms a word); src/motion.js reads the "reduce motion" setting. It is 168 px wide, or 132 px when Helper's window is under 420 px wide or the page under 600 px high (src/layout.js).
  • The team's files are copied at the checksums each job names (tests/lib/team-pins.mjs); when the team's own file has moved on since, the tests print a note and a later job ports it.
  • npm test runs every test in the committed AI_MODE, then again in the other two (scripts/test-modes.mjs; the switch is changed only in what the tests load). It runs offline with Node only: build is current, node --check, colour lint, plugin shape, model check, card rules, key check, step data checks (sources, word limits, answer cards), Helper's answers compared turn by turn with the content team's own reference script, hhtech's ten typed messages from his newcomer run and "my chat app is WhatsApp" (with his kept record, the wants on), the older "Kept:" lines struck through once forgotten, the wants compared on every message of the team's test sets (296) with hhtech's reference steps and hhcontent's wants fixes layer, hhcontent's 53 wants-fixes cases (run_wf1.py), the wants data's build checks (each broken on purpose), the content team's 57 refusal cases, the settings page's read-back compared case by case with the content team's own settings_read.py, every record the conversation keeps read back by the settings page, the build checks on the talk data, the style sheet's rules, every stored key against an allowed list (and no browser storage or cookies), the character (each expression's shapes, when each shows, the word-by-word reveal, the eye maths, the rising, reduce motion), and the page, the conversation, the settings page and the tab rendered with stand-ins for React and Hermes.
  • scripts/hermes-checks.sh (needs a Hermes v0.23.0 checkout and venv): Hermes's desktop lint, hermes plugins validate, and a check that every class the page uses exists in Hermes's own built CSS.
  • The look: the left side wears Hermes's own UI kit components, plus class strings copied from Hermes's own screens (src/look.js, table K; each group names its source file). Helper's window wears the classes of src/talk.css (table T). No colours or fonts of its own anywhere.
  • The model's name is shown the way Hermes's own model button shows it ("Mock Small", "Opus 4.8"); on the free tier it says "Nous · free tier". src/model-name.js holds those naming rules, adapted from Hermes Agent (MIT License, Copyright (c) 2025 Nous Research, apps/desktop/src/lib/model-status-label.ts).

Known issues

  • No __init__.py on purpose: it is a desktop-only plugin, so hermes plugins validate shows the expected warning "capability probe skipped (manifest-only plugin)".
  • Helper's set-up conversation compares your main bot's SOUL.md with Hermes's own starter texts (copied from Hermes v0.23.0). If a later Hermes changes that text, an untouched file would count as a personality of your own.
  • If your SOUL.md exists but Hermes can't read it (for example its permissions), Hermes uses the built-in personality and Helper's set-up conversation counts no personality of your own; it can't tell that the file is there.
  • The pasted-key check also stops a long run of letters and digits that isn't a key (for example a 40-character git commit id). That one message just isn't sent.
  • The model-name rules are a copy of Hermes v0.23.0's. If a later Hermes changes how its model button names models, the page can differ until the copy is updated (a test compares the two wherever the Hermes source is checked out).
  • A source tag names a docs file and line; the docs page opens at its top, not at that line.
  • In a wide window Helper's window cannot be hidden; it can be made as narrow as 360 px.
  • On a Hermes without plugin settings pages, Helper's page in Settings is not there; "See what I keep" then shows the list in the conversation, with "Delete all of it".
  • Answers to pick go to one column when a label would wrap (at 360 px the four topics, at 460 px the three under "What Hermes can do"), so the message box grows taller there.

Licence

MIT, see LICENSE. src/model-name.js is adapted from Hermes Agent, MIT License, Copyright (c) 2025 Nous Research.

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

Developer Mode

Explore built-in Hermes toolsets and actions.

HermesAgent

Developer?

Create a Hermes extension for Desktop or agent workflows.

Developer Section