The agent that grows with you


Contributing #

Thank you for contributing to Hermes Agent! This guide covers setting up your dev environment, understanding the codebase, and getting your PR merged.

Contribution Priorities #

We value contributions in this order:

  1. Bug fixes — crashes, incorrect behavior, data loss
  2. Cross-platform compatibility — macOS, different Linux distros, WSL2
  3. Security hardening — shell injection, prompt injection, path traversal
  4. Performance and robustness — retry logic, error handling, graceful degradation
  5. New skills — broadly useful ones (see Creating Skills)
  6. New tools — rarely needed; most capabilities should be skills
  7. Documentation — fixes, clarifications, new examples

Common contribution paths #

Development Setup #

Prerequisites #

Requirement Notes
Git With --recurse-submodules support, and the git-lfs extension installed
Python 3.11+ uv will install it if missing
uv Fast Python package manager (install)
Node.js 20+ Optional — needed for browser tools and WhatsApp bridge (matches root package.json engines)

Clone and Install #

git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent

# Create venv with Python 3.11
uv venv venv --python 3.11
export VIRTUAL_ENV="$(pwd)/venv"

# Install with all extras (messaging, cron, CLI menus, dev tools)
uv pip install -e ".[all,dev]"
uv pip install -e "./tinker-atropos"

# Optional: browser tools
npm install

Configure for Development #

mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills}
cp cli-config.yaml.example ~/.hermes/config.yaml
touch ~/.hermes/.env

# Add at minimum an LLM provider key:
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env

Run #

# Symlink for global access
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

# Verify
hermes doctor
hermes chat -q "Hello"

Run Tests #

pytest tests/ -v

Code Style #

  • PEP 8 with practical exceptions (no strict line length enforcement)
  • Comments: Only when explaining non-obvious intent, trade-offs, or API quirks
  • Error handling: Catch specific exceptions. Use logger.warning()/logger.error() with exc_info=True for unexpected errors
  • Cross-platform: Never assume Unix (see below)
  • Profile-safe paths: Never hardcode ~/.hermes — use get_hermes_home() from hermes_constants for code paths and display_hermes_home() for user-facing messages. See AGENTS.md for full rules.

Cross-Platform Compatibility #

Hermes officially supports Linux, macOS, and WSL2. Native Windows is not supported, but the codebase includes some defensive coding patterns to avoid hard crashes in edge cases. Key rules:

1. termios and fcntl are Unix-only #

Always catch both ImportError and NotImplementedError:

try:
    from simple_term_menu import TerminalMenu
    menu = TerminalMenu(options)
    idx = menu.show()
except (ImportError, NotImplementedError):
    # Fallback: numbered menu
    for i, opt in enumerate(options):
        print(f"  {i+1}. {opt}")
    idx = int(input("Choice: ")) - 1

2. File encoding #

Some environments may save .env files in non-UTF-8 encodings:

try:
    load_dotenv(env_path)
except UnicodeDecodeError:
    load_dotenv(env_path, encoding="latin-1")

3. Process management #

os.setsid(), os.killpg(), and signal handling differ across platforms:

import platform
if platform.system() != "Windows":
    kwargs["preexec_fn"] = os.setsid

4. Path separators #

Use pathlib.Path instead of string concatenation with /.

Security Considerations #

Hermes has terminal access. Security matters.

Existing Protections #

Layer Implementation
Sudo password piping Uses shlex.quote() to prevent shell injection
Dangerous command detection Regex patterns in tools/approval.py with user approval flow
Cron prompt injection Scanner blocks instruction-override patterns
Write deny list Protected paths resolved via os.path.realpath() to prevent symlink bypass
Skills guard Security scanner for hub-installed skills
Code execution sandbox Child process runs with API keys stripped
Container hardening Docker: all capabilities dropped, no privilege escalation, PID limits

Contributing Security-Sensitive Code #

  • Always use shlex.quote() when interpolating user input into shell commands
  • Resolve symlinks with os.path.realpath() before access control checks
  • Don't log secrets
  • Catch broad exceptions around tool execution
  • Test on all platforms if your change touches file paths or processes

Pull Request Process #

Branch Naming #

fix/description        # Bug fixes
feat/description       # New features
docs/description       # Documentation
test/description       # Tests
refactor/description   # Code restructuring

Before Submitting #

  1. Run tests: pytest tests/ -v
  2. Test manually: Run hermes and exercise the code path you changed
  3. Check cross-platform impact: Consider macOS and different Linux distros
  4. Keep PRs focused: One logical change per PR

PR Description #

Include:

  • What changed and why
  • How to test it
  • What platforms you tested on
  • Reference any related issues

Commit Messages #

We use Conventional Commits:

<type>(<scope>): <description>
Type Use for
fix Bug fixes
feat New features
docs Documentation
test Tests
refactor Code restructuring
chore Build, CI, dependency updates

Scopes: cli, gateway, tools, skills, agent, install, whatsapp, security

Examples:

fix(cli): prevent crash in save_config_value when model is a string
feat(gateway): add WhatsApp multi-user session isolation
fix(security): prevent shell injection in sudo password piping

Reporting Issues #

  • Use GitHub Issues
  • Include: OS, Python version, Hermes version (hermes version), full error traceback
  • Include steps to reproduce
  • Check existing issues before creating duplicates
  • For security vulnerabilities, please report privately

Community #

  • Discord: discord.gg/NousResearch
  • GitHub Discussions: For design proposals and architecture discussions
  • Skills Hub: Upload specialized skills and share with the community

License #

By contributing, you agree that your contributions will be licensed under the MIT License.