贡献指南
感谢您为 Hermes Agent 做出贡献!本指南涵盖设置开发环境、理解代码库以及提交您的 PR 并成功合并的流程。
贡献优先级
我们按以下顺序重视贡献:
- 缺陷修复 —— 崩溃、错误行为、数据丢失
- 跨平台兼容性 —— macOS、不同 Linux 发行版、WSL2
- 安全加固 —— shell 注入、提示注入、路径遍历
- 性能与健壮性 —— 重试逻辑、错误处理、优雅降级
- 新技能 —— 广泛有用的技能(参见 创建技能)
- 新工具 —— 较少需要;大多数功能应通过技能实现
- 文档 —— 修复、澄清、新增示例
常见贡献路径
开发环境设置
前提条件
| 要求 | 说明 |
|---|---|
| Git | 需支持 --recurse-submodules |
| Python 3.11+ | 若缺失,uv 会自动安装 |
| uv | 快速的 Python 包管理器 (安装指南) |
| Node.js 18+ | 可选 —— 用于浏览器工具和 WhatsApp 桥接 |
克隆与安装
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
开发配置
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
运行
# Symlink for global access
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# Verify
hermes doctor
hermes chat -q "Hello"
运行测试
pytest tests/ -v
代码风格
- PEP 8,允许实际例外(不强制行长度限制)
- 注释:仅在解释非显而易见的意图、权衡或 API 特性时使用
- 错误处理:捕获具体异常。对于意外错误,使用
logger.warning()/logger.error()并传入exc_info=True - 跨平台:永远不要假设为 Unix 系统(见下文)
- 安全路径:永远不要硬编码
~/.hermes—— 代码路径请使用hermes_constants中的get_hermes_home(),用户提示信息请使用display_hermes_home()。完整规则参见 AGENTS.md
跨平台兼容性
Hermes 官方支持 Linux、macOS 和 WSL2。原生 Windows 不支持,但代码库包含一些防御性编码模式,以避免在边缘情况下发生硬崩溃。关键规则如下:
1. termios 和 fcntl 仅限 Unix
始终捕获 ImportError 和 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. 文件编码
某些环境可能以非 UTF-8 编码保存 .env 文件:
try:
load_dotenv(env_path)
except UnicodeDecodeError:
load_dotenv(env_path, encoding="latin-1")
3. 进程管理
os.setsid()、os.killpg() 和信号处理在不同平台间存在差异:
import platform
if platform.system() != "Windows":
kwargs["preexec_fn"] = os.setsid
4. 路径分隔符
请使用 pathlib.Path,而非字符串拼接使用 /。
安全注意事项
Hermes 拥有终端访问权限,安全至关重要。
现有防护措施
| 层级 | 实现方式 |
|---|---|
| sudo 密码管道 | 使用 shlex.quote() 防止 shell 注入 |
| 危险命令检测 | tools/approval.py 中的正则模式,配合用户确认流程 |
| Cron 提示注入 | 扫描器阻止指令覆盖模式 |
| 写入拒绝列表 | 受保护路径通过 os.path.realpath() 解析,防止符号链接绕过 |
| 技能防护 | 用于 hub 安装技能的安全扫描器 |
| 代码执行沙箱 | 子进程运行时剥离 API 密钥 |
| 容器加固 | Docker:所有能力被移除,无权限提升,PID 限制 |
贡献安全敏感代码
- 在将用户输入插入 shell 命令时,始终使用
shlex.quote() - 在访问控制检查前,使用
os.path.realpath()解析符号链接 - 不要记录密钥
- 在工具执行周围捕获宽泛异常
- 若您的更改涉及文件路径或进程,请在所有平台上进行测试
拉取请求流程
分支命名
fix/description # Bug fixes
feat/description # New features
docs/description # Documentation
test/description # Tests
refactor/description # Code restructuring
提交前检查
- 运行测试:
pytest tests/ -v - 手动测试:运行
hermes并测试您修改的代码路径 - 检查跨平台影响:考虑 macOS 和不同 Linux 发行版
- 保持 PR 聚焦:每个 PR 仅包含一个逻辑变更
PR 描述
请包含:
- 变更内容 及 原因
- 如何测试 该变更
- 测试过的平台
- 引用任何相关问题
提交信息
我们使用 Conventional Commits:
<type>(<scope>): <description>
| 类型 | 用途 |
|---|---|
fix | 修复缺陷 |
feat | 新功能 |
docs | 文档 |
test | 测试 |
refactor | 代码重构 |
chore | 构建、CI、依赖更新 |
作用域:cli、gateway、tools、skills、agent、install、whatsapp、security
示例:
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
报告问题
- 使用 GitHub Issues
- 请包含:操作系统、Python 版本、Hermes 版本(
hermes version命令输出),以及完整的错误堆栈追踪 - 请提供复现步骤
- 创建新问题前,请先检查是否存在重复问题
- 如发现安全漏洞,请私密报告
社区
- Discord: discord.gg/NousResearch
- GitHub Discussions:用于设计提案和架构讨论
- Skills Hub:上传专业技能并与其他社区成员共享
许可证
通过贡献,您同意您的贡献将遵循 MIT 许可证。