Table of contents
Building On and Into Hermes
Hermes is an open source Python project, MIT-licensed, and actively accepts outside contributions. This lesson covers the dev environment, the code-quality rules, the cross-platform and security invariants the reviewers care about, the three extension paths, and the commit/PR conventions.
Primary source: the contributing guide at https://hermes-agent.nousresearch.com/docs/developer-guide/contributing. Always cross-check against that page before you send a PR — conventions can drift.
Contribution Priorities
Hermes ranks contributions clearly — this is worth internalising before you pick what to work on:
- Bug fixes — crashes, incorrect behaviour, data loss.
- Cross-platform compatibility.
- Security hardening.
- Performance improvements.
- New features.
An agent with terminal access has more to lose than gain from speculative new features, so the ordering reflects that.
Dev Environment Setup
You'll need:
- Python 3.11+.
- Git with LFS — the repo uses LFS for some assets.
uvas the package manager (not pip directly).- A
~/.hermes/config tree withconfig.yaml,.env, and the standard subdirectories (sessions, logs, memories, skills). - At least one LLM provider API key in
.envfor local testing.
Clone with submodules (git clone --recurse-submodules), create a venv with uv venv, and install dependencies with all extras enabled so tests for optional integrations can run.
Code Quality Standards
The codebase follows PEP 8 with practical exceptions, and the style guide is explicit: minimal, intent-focused comments. Prefer a clear name and a short docstring over a paragraph explaining what the code already shows.
On error handling: catch specific exceptions, not broad ones. Log unexpected errors with logger.warning() or logger.error() and exc_info=True so the traceback actually lands in the logs.
One non-obvious rule worth knowing: never hardcode paths like ~/.hermes. Use get_hermes_home() for internal logic and display_hermes_home() for anything user-facing. Multi-profile installs rely on this — hardcoding breaks them silently.
Cross-Platform Invariants
Officially supported: Linux, macOS, WSL2. But the code is written defensively enough to run on raw Windows too. Three patterns come up repeatedly:
- Unix-only modules (
termios,fcntl) must be imported in a try/except that catches bothImportErrorandNotImplementedError. - File encoding must fall back to latin-1 when the locale isn't UTF-8 — assume nothing about the environment.
- Paths are always
pathlib.Path, not string concatenation. This is enforced by review.
Security-First Design
Hermes runs with terminal capabilities by default, so security is treated as a code-review invariant, not a feature:
- Shell injection prevention with
shlex.quote()for any user input interpolated into shell commands. - Symlink resolution via
os.path.realpath()before access-control checks. - A regex-based dangerous command detector that forces user approval on risky commands.
- Hub-downloaded skills are security-scanned before use.
- Sandboxed code execution strips API keys from child process environments.
- Container deployments drop all Linux capabilities and enforce PID limits.
Don't log secrets. If you're changing anything that touches file paths or subprocess management, manually test on multiple platforms — reviewers will ask.
Extension: Three Paths
There are three well-defined ways to extend Hermes without forking:
- Tools — the lowest-level primitive. Follow the 'Adding Tools' doc.
- Skills — higher-level procedures. Follow the 'Creating Skills' doc and the agentskills.io open standard.
- Providers — new inference backends. Follow the 'Adding Providers' doc.
These three layers are deliberately separated. If you find yourself wanting to reach from a provider implementation into terminal tool internals, step back — that's usually a sign the work belongs in a different layer.
Testing and PR Etiquette
Before sending a PR: pytest tests/ -v. Manually test any changed code path. Keep PRs to one logical change — atomic is easier to review than heroic.
Branch names follow a strict prefix convention: fix/, feat/, docs/, test/, refactor/. Commits are Conventional Commits with scope qualifiers (cli, gateway, tools, skills, agent, install, whatsapp, security). A commit message like feat(gateway): add Matrix voice support signals exactly what changed and where.
PR descriptions should cover: what changed, why, how you tested, which platforms you tested on, and any related issues. Issue reports need OS info, Python version, hermes version output, the full traceback, and a reproduction.
Community
Contributions happen on GitHub via Issues and Discussions; realtime discussion happens on Discord. MIT licensed throughout, so the legal story is simple for both enterprise users and community contributors.
Next Steps
Lesson 8 is the CLI command reference — handy both for day-to-day use and for understanding the surface area before writing a plugin. If you want the reference to stay with you, bookmark /learn/hermes/reference/ and come back to it per command.