CLI tool
joeynyc/hermes-skins avatar
joeynyc/hermes-skins

hermes-skins reskins the Hermes CLI agent without touching its behaviour

Custom skins (visual themes) for the Hermes CLI agent

619 stars35 forksPythonMIT

At a glance

What is it?
hermes-skins is a collection of YAML themes for the Hermes CLI agent, covering banner colours, spinner verbs, response labels, tool activity prefixes and ASCII art, installed by copying a file into ~/.hermes/skins and switching with a slash command. The skins are pure presentation, the merge is forgiving, and an unknown skin name falls back silently.
Who is it for?
hermes-skins fits a Hermes user who wants the CLI to look like something other than the default gold and kawaii, and who is comfortable writing or editing a small YAML file when the built in themes do not match.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Presentation only, and the project says so

The scope statement in the README is short and worth quoting rather than paraphrasing. Skins control the visual presentation of Hermes: banner colors, spinner faces and verbs, response-box labels, branding text, tool activity prefix, and ASCII art banners. They do not affect personality or behavior, just how things look.

That boundary is what makes this a small, low risk dependency. There is no plugin API, no hook into the agent's decision making, no change to how tools are called. A skin is a set of strings and colors, and switching between them cannot alter what the agent does.

The target is the Hermes CLI agent from Nous Research, and the project is one repository of themes for it. The topics say so directly: cli, customization, hermes, hermes-agent, skins, themes. The license is MIT, the primary language is Python, and the repository is not archived. The last push was on 2026-06-28 and the repository has no GitHub releases at all, so the versions of the skins are tracked only in git history and in the file names.

The repository layout is correspondingly light: a skins directory holding the YAML files, a screenshots directory, a template.yaml, a SCHEMA.md describing the full set of configurable keys, a generate_screenshots.py script, a validate_skins.py script, and a requirements.txt listing rich, ansi2html, html2image, Pillow and PyYAML, which are the dependencies of the screenshot tooling rather than of the skins themselves.

Installing a skin is copying one file

The quick start is three steps: browse the skins directory and pick one, copy the .yaml file to ~/.hermes/skins/, and activate it.

Activation has two forms, one for the current session and one for permanent use:

bash
# Session-only
/skin pirate

# Permanent (add to ~/.hermes/config.yaml)
display:
  skin: pirate

The slash command is typed inside Hermes itself, so the change lasts as long as the session. The permanent form adds a display key with a skin name to the main config file, which is the same place the rest of the agent's configuration lives.

There is no installer, no plugin registration and no package to add to a dependency list. The file is YAML, Hermes reads it, and the theme changes. That simplicity is the main argument for the project and the main limitation of it, since a theme you want to share with someone else is a file you have to send them.

The two built in ways of changing things also make the boundary visible. Hermes loads skins from two locations, and user skins take priority: the user directory at ~/.hermes/skins/<name>.yaml, and the built in skins that are hardcoded in skin_engine.py inside the Hermes source. So a user skin always wins over a shipped one, which means you can override a built in theme without editing anything you do not own.

The merge on top of default is what makes partial skins viable

The engine merges your skin on top of default, so partial skins work fine, and anything you do not specify inherits from the default skin. That single design decision is what keeps the YAML files short and what makes writing your own a realistic afternoon.

The minimal example in the documentation shows how little is needed:

yaml
name: cyberpunk
description: Neon terminal theme

colors:
  banner_border: "#FF00FF"
  banner_title: "#00FFFF"
  banner_accent: "#FF1493"

spinner:
  thinking_verbs: ["jacking in", "decrypting", "uploading"]

Three color keys, three spinner verbs, a name and a description. A skin that overrides only the banner colors inherits everything else from the default theme.

The cost of that forgiveness shows up elsewhere. The contributing guide asks authors to define all 28 color keys, and explains why in one line: dark skins that omit the status_bar_ and completion_menu_ keys will get mismatched colors from the default theme. In other words, the merge is convenient for a quick experiment and a trap for a finished skin, because the default theme is light in those regions and a dark theme that leaves them unset will produce a banner that does not match its own status bar.

The complete list of configurable keys is documented separately in SCHEMA.md, and there is a template.yaml in the repository, which are the two places to start when writing something new rather than copying an existing theme.

Unknown skin names fail silently

One behaviour in the documentation deserves attention because it is the kind of detail that saves an hour of debugging, and the kind that also hides a mistake.

Unknown skin names silently fall back to default. There is no error, no warning, no non-zero exit. If you type /skin pirate and the file is in the wrong place, or the name is misspelled, or the YAML has a syntax error that the loader tolerates, you get the default skin and no indication why.

The same applies to the permanent form. A display key with a skin value of piate, misspelled, produces a working Hermes with the default appearance.

This is a deliberate design choice in most theme systems, where a missing theme should never break the tool, and it is defensible. But it does mean that a theme that appears not to apply is indistinguishable from a theme that applied and looked like the default. If you are debugging, the check is whether the file is in ~/.hermes/skins with a name matching the file, and whether its name field matches the file name too.

That last requirement is spelled out in the quick start for your own skins: drop a YAML file in ~/.hermes/skins/<name>.yaml, and the name field inside must match the filename. Two names to keep in sync, one of which fails silently.

The catalogue is wide and deliberately nostalgic

The custom skins are the reason to look at this repository, and they fall into two groups.

One group is retro computing and terminal nostalgia. Vault-Tec is described as a Fallout terminal with green phosphor CRT on black. DOS is an MS-DOS Norton Commander revival with a dual pane file manager hero, C:\ and D:\ directories, cyan borders, a yellow F-key shortcut bar, an EGA 16-colour palette, a C:\> prompt and an F1 - HELP.COM header. Telemate is a DOS BBS terminal revival with a splash screen hero, an ATDT dial sequence, a cyan status bar, modem-era spinner verbs such as DIALING, HANDSHAKE and CARRIER DETECT, an ATDT prompt, a CONNECT 57600 welcome and a NO CARRIER goodbye. Mother is a Weyland-Yutani MU-TH-UR 6000 with amber CRT phosphor fused with HAL 9000's red eye.

The other group is anime and science fiction. Lain uses Serial Experiments Lain braille art and a Wired protocol aesthetic. Netrunner is a cyberpunk neural interface theme with cyan ICE-breaking colours. Skynet is a Cyberdyne Systems defense network with a glowing-eye pyramid and red to white gradient text. Empire is a Galactic Empire Death Star firing control terminal with a targeting grid, canon Imperial red #C8102E and a targeting reticle prompt. Mythos pairs an Eye of Providence with Prometheus Labs branding. Sakura and Bubblegum 80s are the gentle and loud ends of the pastel range.

Two skins are aimed at a specific audience rather than a mood. Nous is a tribute to Nous Research itself, with anime mascot braille art and a warm amber and gold palette matching the Nous brand color #DD8E35. DGX Spark is for NVIDIA DGX Spark owners, with signature NVIDIA green, champagne gold, GB10 Grace Blackwell branding and compute themed spinner verbs.

The built in skins, which ship with every Hermes install, are listed in the README for reference: default in classic gold and kawaii, ares, mono, slate, poseidon, sisyphus and charizard.

Contributing a skin has a defined checklist

The contributing section is short and reads like a build checklist, which is useful because a skin that is mostly colours is easy to get subtly wrong.

There are six steps. Add your .yaml to the skins directory, include a brief description at the top, make sure it has a name key matching the filename, define all 28 color keys as described earlier, run the screenshot generator and include the screenshot, and update the table in the README.

Two of those steps need tooling. The screenshot script is invoked with python3 generate_screenshots.py, and the repository also carries a validate_skins.py script, which is not described in the README excerpt but is named in the file listing and is the obvious companion for the step about validating the name field and the color keys. The requirements.txt file lists rich, ansi2html, html2image, Pillow and PyYAML, which are what the screenshot pipeline needs to render a terminal session with colours into an image.

The screenshot step is not cosmetic. Every skin in the catalogue is accompanied by a PNG in the screenshots directory, and the README shows the result next to each description. Since a skin is judged on how it looks in a terminal, showing it is the only way for someone else to see it, and it is also how you check your own colour choices against a real Hermes session rather than against the default theme's assumptions.

Contributions are welcome as pull requests, and the project maintains a CONTRIBUTING.md file alongside a .editorconfig.

Where this is the wrong answer

Three cases rule it out.

The first is anyone who wants to change what the agent does. The project rules that out explicitly: skins do not affect personality or behavior. The configurable surface is banner colours, spinner faces and verbs, response-box labels, branding text, the tool activity prefix and ASCII art. If your goal is a different system prompt, a different tool set or different output format, this repository has nothing for you.

The second is a shared or production environment. A skin in ~/.hermes/skins overrides a built in theme for that user, and a permanent skin in config.yaml changes the appearance for every session that user starts. That is fine for one person at a terminal and wrong for a fleet where a shared home directory or a config template would push a joke theme onto everyone, including a demo to a client. The same applies to recording: a screencast of your session captures the skin, so a theme is a decision about how your work looks to others.

The third is a team that wants a maintained theme catalogue. There are no GitHub releases, so there is no versioned distribution channel, and the catalogue lives in a single repository whose last push was on 2026-06-28. The theme files are self contained YAML, so forking or vendoring them is easy, and that is the realistic model of use: take the file, keep it under your own version control, and adjust it as the Hermes schema evolves.

The alternative is to write the YAML yourself. The schema is small enough that the official skins are essentially a gallery of examples, and template.yaml plus SCHEMA.md give you the full set of keys. Given that a skin changes nothing about behaviour, building your own is a reasonable default rather than a fallback, and using these as a starting point is the sensible middle path.

Editorial conclusion

hermes-skins fits a Hermes user who wants the CLI to look like something other than the default gold and kawaii, and who is comfortable writing or editing a small YAML file when the built in themes do not match. It is the wrong choice for anyone looking to change how the agent behaves, since the project is explicit that skins do not affect personality or behaviour, and it is the wrong choice for a shared production environment where a stray skin file changes what every user sees. Before adopting one, check three things: that your skin defines all 28 color keys, because the contributing guide warns that dark skins omitting the status_bar_ and completion_menu_ keys inherit mismatched colours from the default theme, that the name field matches the filename, since Hermes silently falls back to the default for an unknown name, and that the skin loads from ~/.hermes/skins rather than being expected somewhere else. The last push was on 2026-06-28, more than three months before this writing, and the repository publishes no GitHub releases.

Frequently asked questions

How do I install a skin for the Hermes CLI agent?

Copy the .yaml file from the skins directory into ~/.hermes/skins/, then activate it with the /skin command for the current session, or add a display key with a skin name to ~/.hermes/config.yaml to make it permanent.

Do Hermes skins change the agent's behaviour?

No. The project states that skins control only the visual presentation, covering banner colors, spinner faces and verbs, response-box labels, branding text, the tool activity prefix and ASCII art banners. They do not affect personality or behavior.

What happens if I activate a Hermes skin that does not exist?

Unknown skin names silently fall back to default, so a misspelled name or a file in the wrong place gives you the default theme with no error message. The name field inside a skin file must also match the file name.

Do I have to define every color in a Hermes skin?

No, since the engine merges your skin on top of default and missing values inherit. However the contributing guide asks for all 28 color keys, and warns that dark skins omitting the status_bar_ and completion_menu_ keys get mismatched colors from the default theme.

Where does Hermes load skins from?

From two locations, with user skins taking priority: ~/.hermes/skins/<name>.yaml for user custom skins, and the built-in skins hardcoded in skin_engine.py. The complete list of configurable keys is in SCHEMA.md, and template.yaml is provided as a starting point.

Official sources

  1. Issues
  2. joeynyc/hermes-skins on GitHub
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/joeynyc-hermes-skins.svg)](https://hysenlabs.com/projects/joeynyc-hermes-skins)

Was this useful?