| --- |
| sidebar_position: 4 |
| title: "Contributing" |
| description: "How to contribute to Hermes Agent β dev setup, code style, PR process" |
| --- |
| |
| # 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](creating-skills.md)) |
| 6. **New tools** β rarely needed; most capabilities should be skills |
| 7. **Documentation** β fixes, clarifications, new examples |
|
|
| ## Common contribution paths |
|
|
| - Building a new tool? Start with [Adding Tools](./adding-tools.md) |
| - Building a new skill? Start with [Creating Skills](./creating-skills.md) |
| - Building a new inference provider? Start with [Adding Providers](./adding-providers.md) |
|
|
| ## Development Setup |
|
|
| ### Prerequisites |
|
|
| | Requirement | Notes | |
| |-------------|-------| |
| | **Git** | With `--recurse-submodules` support | |
| | **Python 3.10+** | uv will install it if missing | |
| | **uv** | Fast Python package manager ([install](https://docs.astral.sh/uv/)) | |
| | **Node.js 18+** | Optional β needed for browser tools and WhatsApp bridge | |
|
|
| ### Clone and Install |
|
|
| ```bash |
| 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 |
|
|
| ```bash |
| 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 |
|
|
| ```bash |
| # 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 |
|
|
| ```bash |
| 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) |
|
|
| ## 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`: |
|
|
| ```python |
| 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: |
|
|
| ```python |
| 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: |
|
|
| ```python |
| 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](https://www.conventionalcommits.org/): |
|
|
| ``` |
| <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](https://github.com/NousResearch/hermes-agent/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](https://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](https://github.com/NousResearch/hermes-agent/blob/main/LICENSE). |
|
|