Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add AtlasOmnia/donna-starter --skill hermes-desktop-pluginsgit clone --depth 1 https://github.com/AtlasOmnia/donna-starterWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/atlasomnia/donna-starter/hermes-desktop-plugins)<a href="https://agentmods.dev/skills/atlasomnia/donna-starter/hermes-desktop-plugins"><img src="https://agentmods.dev/badge/skills/atlasomnia/donna-starter/hermes-desktop-plugins.svg" alt="Measured on agentmods" height="20"></a>- NVIDIA SkillSpector warn
SkillSpector: 1 finding, up to medium
These are SkillSpector’s own severities. On a checked sample its high-severity flags on skills were ~96% false positives — a documented command, a public API, a “never do X” rule — so we show them as a caution to read, not a verdict. Why →
- medium Rogue Agent · line 3 Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.Fix: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.
What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00025 | $0.02292 |
| Opus 5 | $0.00013 | $0.01146 |
| Sonnet 5 | $0.00005 | $0.00458 |
| Haiku 4.5 | $0.00003 | $0.00229 |
Grade A, and why
hermes-desktop-plugins scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
Copies of this mod
4 near-identical copies found in the catalogue:
- hermes-desktop-plugins — 100% identical, 181 lines differ
- hermes-desktop-plugins — 100% identical, 0 lines differ
- hermes-desktop-plugins — 88% identical, 175 lines differ
- hermes-desktop-plugins — 84% identical, 176 lines differ
How it starts
The opening of the file, as written. The whole thing — 174 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Hermes Desktop Plugins Skill
Write plugins for the Hermes desktop app: statusbar items, layout panes,
command-palette commands, keybinds, routes, and themes. A plugin is a single
plain-JavaScript ESM file the app loads at runtime — no build step, no repo
changes. A plugin can also talk to its own Python backend namespace
(ctx.rest/ctx.socket → /api/plugins/<id>); the general Python plugin
system (~/.hermes/plugins/) is otherwise documented separately.
Full human reference (every export, area payloads, backend, security):
website/docs/developer-guide/desktop-plugin-sdk.md.
When to Use
- The user asks for a new desktop UI element (a pane, a statusbar widget, a dashboard, a command) without modifying the app itself.
- You want to surface data you compute (via gateway RPC) inside the app.
Prerequisites
- The Hermes desktop app (it loads plugins; the CLI/gateway alone does not).
- Write access to
$HERMES_HOME/desktop-plugins/(usually~/.hermes/desktop-plugins/).
How to Run
- Create
$HERMES_HOME/desktop-plugins/<name>/plugin.jsfromtemplates/plugin.js(relative to this skill directory) — that's~/.hermes/...by default, or~/.hermes/profiles/<profile>/...under a named profile. Keep<name>equal to the pluginid. - The desktop app watches that directory: the plugin loads within a few seconds of the file landing, and every later save hot-reloads it in place. No reload step. (Fallback if it doesn't appear: ⌘K → Reload desktop plugins.)
- If loading fails the app shows a toast naming the error — fix the file and save again.
Quick Reference
The ONLY import surface is @hermes/plugin-sdk (plus react /
react/jsx-runtime, which resolve to the app's own React — write UI with
jsx() calls, not JSX syntax; the file is not compiled).
host.state.*— readonly reactive atoms:activeSessionId,cwd,gateway,model,profile,viewport. Read with.get()in handlers,useValue(atom)in components.host.request(method, params)— gateway JSON-RPC (sessions, config, skills, cron — everything the app uses).host.onEvent(type, fn)— live gateway events ('*'for all). Returns a disposer.host.notify({ kind, message }),host.navigate(path),host.logs(...),host.status(),haptic('tap').ctx.register({ id, area, order?, render?, data? })— contribute UI. Key areas:'statusBar.right'/'statusBar.left'(chips),'panes'(layout zones — settitleanddata: { placement, dock?, width?, height? }; the pane auto-joins a matching zone),PALETTE_AREA(⌘K commands),KEYBINDS_AREA(rebindable actions).- Pane placement:
placement: 'left'|'right'|'bottom'|'main'is the semantic role — the pane stacks (tabs) with existing panes of that role. To land on a specific EDGE instead, adddock: { pane, pos }— the same gesture as dragging onto a pane's drop chip.paneis any pane id (workspaceis the main thread; alsosessions,terminal,files,review,logs),posis'top'|'bottom'|'left'|'right'|'center'. E.g. "below the conversation" =dock: { pane: 'workspace', pos: 'bottom' }— declare aheight(e.g.'200px') so it doesn't take half the zone. - Full PAGES: register
area: ROUTES_AREAwithdata: { path: '/my-page' }and arender— the page mounts in the workspace (main) pane like any built-in view. Make it reachable with a sidebar nav row:ctx.register({ id: 'nav', area: SIDEBAR_NAV_AREA, data: { path: '/my-page', label: 'My Page', codicon: 'project' } })(renders below Artifacts, lights up at the route) — and/or aPALETTE_AREAcommand callinghost.navigate('/my-page'). ctx.storage.get/set/remove— persistence namespaced to your plugin.ctx.i18n.register({ en, ja, ... })— ship your OWN locale bundles, scoped to your plugin (never edit coreen.ts). Values are literal strings or interpolator functions; nested trees are addressed by dot-path. Read them reactively in components withusePluginI18n(id)returningt('key', ...args)(re-renders on a locale switch), or viactx.i18n.tin handlers/stores. Resolution follows the app's active locale, then youren, then the raw key.- Data:
useQuery/useMutation/useQueryClient/queryClient(the app's ONE React Query client — cache, dedupe,refetchInterval, invalidate like core; never hand-roll a poll loop), plusatom/computedfor plugin-local state. - Backend: if the plugin ships a Python
plugin_api.py(under~/.hermes/plugins/<id>/dashboard/, manifest"api": "plugin_api.py"), reach it withctx.rest('/path', { method?, body?, timeoutMs? })and its live twinctx.socket('/events', onMessage)— both scoped to/api/plugins/<id>by construction (traversal rejected).ctx.socketis a no-op on OAuth remotes, so always keep a polling fallback. The Python backend is imported only when the plugin is inplugins.enabledinconfig.yaml(separate from the in-app enable toggle). For gateway-wide data usehost.request/host.onEventinstead. Contribute(mount-scoped): renderjsx(Contribute, { area, id, children })inside a component so page-owned chrome (e.g. a titlebar control inTITLEBAR_AREAS.center) leaves when the page unmounts —ctx.registeris for permanent contributions.defaultEnabled: falseon the default export ships an opt-in plugin: it inventories in Settings → Plugins, off until the user flips it on.- Users manage plugins in Settings → Plugins (enable/disable live, reveal folder). A disabled plugin stays disabled across restarts — don't fight it; the user turned you off.
- UI: the app's design language, importable directly —
Button,Input,Textarea,Select*,Switch,Checkbox,SegmentedControl,Tabs*,Dialog*,ConfirmDialog,DropdownMenu*,ContextMenu*,Popover*,Tip/Tooltip*,Badge,Kbd/KbdGroup,SearchField,ScrollArea,Separator,Skeleton,GlyphSpinner,EmptyState,ErrorState,CopyButton,StatusDot,LogView,Codicon,DecodeText, pluscnandicons.*. Prefer these over hand-rolled elements so the plugin looks native; style with theme vars, never hardcoded colors.
What ships with it
1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 8d ago First seen · 174 lines · 25 tokens per session scan A 79c1efd62aa0
hermes-desktop-plugins is a skill published in the GitHub repository AtlasOmnia/donna-starter (107 stars, last pushed 8d ago), licensed MIT. It adds 25 tokens to every session and 2,292 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other skills, from other repositories
animated-portfolio-sites
Build a one-page animated personal or portfolio site (canvas starfield, rotating galaxies with mouse parallax, hidden accordion/card content, anchor nav) and publish it free on GitHub Pages. Covers the canvas technique and the Pages permission wall, not just one task.
github-pages-portfolio
Build, update, and verify a single-page static portfolio / intro site on GitHub Pages (pure HTML+CSS+JS, no build step). Covers sourcing content read-only from the user's existing GitHub repos (public AND private), the free-tier public-repo requirement, anchor+accordion single-page design (hidden content revealed on…
markdown-site-source-pipeline
Keep a static HTML/JS site's content in an editable Markdown source file; generate the data artifact (JS/JSON) the site consumes; guarantee identical render via semantic deep-equal verification. Use when a user wants to edit a static site (portfolio, docs) in Markdown/Obsidian instead of hand-editing generated data…
markdown-static-site-source
Make a data-driven static site (content lives in a JS/JSON object consumed by a render script) editable from Markdown/Obsidian. Generate the data file from a YAML-frontmatter MD source and verify fidelity with SEMANTIC deep-equal (not byte comparison), keeping the HTML/CSS/render engine untouched so the site renders…
frontend-design-systems
Architect and build production-grade web interfaces with modern design systems: Tailwind CSS v4, Shadcn UI primitives, Radix UI, dark mode tokens, and accessible WCAG AA components.
nextjs-app-router-patterns
Architect and implement modern Next.js App Router applications with Server Components (RSC), Server Actions, Parallel/Intercepting Routes, and Streaming SSR.