Documentação oficial desta página · v0.20.6
Contribuir
Obrigado por contribuir com o Hermes Agent! Este guia cobre como montar o seu ambiente de desenvolvimento, entender a base de código e conseguir que o seu PR seja aceito.
Prioridades de contribuição
Valorizamos as contribuições nesta ordem:
- Correções de bug — travamentos, comportamento errado, perda de dados
- Compatibilidade entre plataformas — macOS, distribuições Linux variadas, WSL2
- Endurecimento de segurança — injeção de shell, injeção de prompt, travessia de caminho
- Desempenho e robustez — lógica de repetição, tratamento de erro, degradação suave
- Skills novas — as de utilidade ampla (veja Criar Skills)
- Ferramentas novas — raramente necessárias; a maioria das capacidades deveria ser skill
- Documentação — correções, esclarecimentos, exemplos novos
Caminhos comuns de contribuição
- Está criando uma ferramenta local/sob medida sem mexer no núcleo do Hermes? Comece por Criar um plugin do Hermes
- Está criando uma ferramenta embutida nova para o próprio Hermes? Comece por Adicionar ferramentas
- Está criando uma skill nova? Comece por Criar Skills
- Está criando um provedor de inferência novo? Comece por Adicionar provedores
Preparar o ambiente de desenvolvimento
Pré-requisitos
| Requisito | Observações |
|---|---|
| Git | Com a extensão git-lfs instalada |
| Python 3.11–3.13 | O uv instala se estiver faltando |
| uv | Gerenciador rápido de pacotes Python (instalação) |
| Node.js 26+ | Opcional — necessário para as ferramentas de navegador e a ponte do WhatsApp (bate com os engines do package.json da raiz) |
Instalar com o instalador padrão
Para a maioria de quem contribui, o melhor caminho de desenvolvimento é o mesmo
que os usuários seguem: rode o instalador padrão e trabalhe dentro do repositório
que ele clonou. O instalador cria o venv do Hermes, liga o comando hermes,
carimba o método de instalação para o hermes update e clona o projeto git
inteiro em $HERMES_HOME/hermes-agent (em geral ~/.hermes/hermes-agent). Isso
mantém o seu ambiente de desenvolvimento no mesmo layout que a CLI, o atualizador,
o instalador preguiçoso de dependências, o gateway e a documentação assumem.
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
cd "${HERMES_HOME:-$HOME/.hermes}/hermes-agent"
# Acrescente os extras de dev/teste por cima da instalação padrão.
uv pip install -e ".[all,dev]"
# Opcional: ferramentas de navegador / dependências do site de documentação.
npm install
Depois disso, crie branches e rode os testes a partir desse checkout:
git checkout -b fix/descricao
scripts/run_tests.sh
Você também pode rodar uma instância do Hermes totalmente isolada (HERMES_HOME descartável, userData do Electron separado, nome de aplicativo Electron distinto para evitar a trava de instância única):
scripts/dev-sandbox.sh python -m hermes_cli.main
scripts/dev-sandbox.sh --persistent python -m hermes_cli.main desktop # o estado sobrevive a reinícios, mas mora na worktree :)
Plano B: clone manual
Use isto só se você não quiser mesmo o layout de instalação gerenciado do Hermes
(por exemplo, um clone descartável dentro de um contêiner ou de um job de CI). Se
você instalar assim, garanta que roda o ponto de entrada hermes deste venv; rodar
o python3 -m hermes_cli.main do sistema pode pegar pacotes Python do sistema sem
relação nenhuma.
Crie o venv fora da árvore de código clonada. Um venv que mora dentro do
diretório de onde o agente opera pode ser apagado por um comando de caminho relativo
que o agente rode contra o próprio checkout (rm -rf venv, uv venv venv, etc.),
o que destrói em silêncio o runtime em execução no meio da sessão. Mantê-lo fora da
árvore significa que nenhum caminho relativo a partir do espaço de trabalho chega até ele.
git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
# Crie o venv com Python 3.11, FORA da árvore de código
uv venv ~/.hermes/venvs/hermes-dev --python 3.11
export VIRTUAL_ENV="$HOME/.hermes/venvs/hermes-dev"
export PATH="$VIRTUAL_ENV/bin:$PATH"
# Instale com todos os extras (mensagens, cron, menus da CLI, ferramentas de dev)
uv pip install -e ".[all,dev]"
# Opcional: ferramentas de navegador
npm install
Configurar para desenvolvimento
mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills}
cp cli-config.yaml.example ~/.hermes/config.yaml
touch ~/.hermes/.env
# Acrescente no mínimo uma chave de provedor de LLM:
echo 'OPENROUTER_API_KEY=sk-or-v1-sua-chave' >> ~/.hermes/.env
Rodar
# O instalador padrão já colocou o `hermes` no PATH.
hermes doctor
hermes chat -q "Olá"
Se você usou o plano B do clone manual, rode ./hermes a partir do checkout ou
crie um link simbólico explícito para o venv deste clone:
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
Rodar os testes
scripts/run_tests.sh
Estilo de código
- PEP 8 com exceções práticas (sem imposição rígida de comprimento de linha)
- Comentários: só quando explicam intenção não óbvia, escolhas de projeto ou manias de API
- Tratamento de erro: capture exceções específicas. Use
logger.warning()/logger.error()comexc_info=Truepara erros inesperados - Entre plataformas: nunca assuma Unix (veja abaixo)
- Caminhos seguros para perfis: nunca fixe
~/.hermesno código — useget_hermes_home()dehermes_constantsnos caminhos de código edisplay_hermes_home()nas mensagens que o usuário vê. Veja o AGENTS.md para as regras completas.
Compatibilidade entre plataformas
Veja Suporte a plataformas. O Windows nativo usa o Git Bash (do Git for Windows) para os comandos de shell. Alguns recursos exigem primitivos de kernel POSIX e ficam limitados: o painel de terminal PTY embutido no dashboard (aba /chat) precisa de um PTY POSIX (Linux, macOS ou WSL2). Se você faz muito desenvolvimento voltado a Windows, rode o lint de armadilhas do Windows (scripts/check-windows-footguns.py) antes de enviar.
Ao contribuir com código, tenha estas regras em mente:
- Não acrescente referências a
signal.SIGKILLsem proteção. Ele não existe no Windows. Ou passe porgateway.status.terminate_pid(pid, force=True)(o primitivo centralizado que faztaskkill /T /Fno Windows e SIGKILL no POSIX), ou recorra agetattr(signal, "SIGKILL", signal.SIGTERM). - Capture
OSErrorjunto comProcessLookupErrornas sondagensos.kill(pid, 0). O Windows levantaOSError(WinError 87, "parameter is incorrect") para um PID que já sumiu, em vez deProcessLookupError. - Não force o terminal à semântica POSIX.
os.setsid,os.killpg,os.getpgideos.forklevantam erro no Windows — proteja-os comif sys.platform != "win32":ouif os.name != "nt":. - Abra arquivos com um
encoding="utf-8"explícito. O padrão do Python no Windows é a localidade do sistema (muitas vezes cp1252), que embaralha ou quebra em texto fora do alfabeto latino. - Use
pathlib.Path/os.path.join— nunca concatene à mão com/. Isso importa menos para as strings que o sistema operacional nos devolve e mais para as strings que construímos para entregar a subprocessos.
Padrões principais:
1. Codificação de arquivo
Alguns ambientes podem salvar arquivos .env em codificações que não são UTF-8:
try:
load_dotenv(env_path)
except UnicodeDecodeError:
load_dotenv(env_path, encoding="latin-1")
2. Gerenciamento de processos
os.setsid(), os.killpg() e o tratamento de sinais variam entre plataformas:
import platform
if platform.system() != "Windows":
kwargs["preexec_fn"] = os.setsid
3. Separadores de caminho
Use pathlib.Path em vez de concatenar strings com /.
Considerações de segurança
O Hermes tem acesso ao terminal. Segurança importa.
Proteções já existentes
| Camada | Implementação |
|---|---|
| Envio da senha de sudo | Usa shlex.quote() para evitar injeção de shell |
| Detecção de comando perigoso | Padrões de regex em tools/approval.py com fluxo de aprovação do usuário |
| Injeção de prompt no cron | O scanner bloqueia padrões de sobrescrita de instrução |
| Lista de negação de escrita | Caminhos protegidos resolvidos por os.path.realpath() para evitar desvio por link simbólico |
| Guarda de skills | Scanner de segurança para skills instaladas pelo hub |
| Sandbox de execução de código | O processo filho roda com as chaves de API removidas |
| Endurecimento de contêiner | Docker: todas as capacidades removidas, sem escalada de privilégio, limites de PID |
Contribuir com código sensível a segurança
- Sempre use
shlex.quote()ao interpolar entrada do usuário em comandos de shell - Resolva links simbólicos com
os.path.realpath()antes das checagens de controle de acesso - Não registre segredos em log
- Capture exceções amplas ao redor da execução de ferramentas
- Teste em todas as plataformas se a sua mudança encosta em caminhos de arquivo ou em processos
Processo de pull request
Nomes de branch
fix/descricao # Correções de bug
feat/descricao # Recursos novos
docs/descricao # Documentação
test/descricao # Testes
refactor/descricao # Reestruturação de código
Antes de enviar
- Rode os testes:
scripts/run_tests.shpara ficar igual à CI. Usepython -m pytest ...direto só quando o wrapper não estiver disponível ou quando você estiver depurando fora dele de propósito. - Teste na mão: rode o
hermese exercite o caminho de código que você mudou - Confira o impacto entre plataformas: pense em macOS, Linux, WSL2 e Windows nativo. Se você encostar em E/S de arquivo, gerenciamento de processos, tratamento de terminal, subprocessos ou sinais, rode o
scripts/check-windows-footguns.py. - Mantenha os PRs focados: uma mudança lógica por PR
Descrição do PR
Inclua:
- O que mudou e por quê
- Como testar
- Em quais plataformas você testou
- Referência a qualquer issue relacionada
Mensagens de commit
Usamos Conventional Commits:
<type>(<scope>): <description>
| Tipo | Use para |
|---|---|
fix | Correções de bug |
feat | Recursos novos |
docs | Documentação |
test | Testes |
refactor | Reestruturação de código |
chore | Build, CI, atualização de dependência |
Escopos: cli, gateway, tools, skills, agent, install, whatsapp, security
Exemplos:
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
Listas de revisão locais do repositório: .agents/checks/*.md
Projetos construídos sobre (ou revisados pelo) Hermes podem manter listas de verificação de revisão dentro do repositório, em .agents/checks/. Cada arquivo é uma lista focada, em markdown puro, que um agente carrega antes de revisar uma mudança que encoste na área correspondente:
.agents/
checks/
security.md # ex.: "procure interpolação de shell no diff; confira se as chamadas de subprocesso citam os argumentos"
migrations.md # ex.: "toda mudança de esquema vem com backfill e nota de reversão"
public-api.md # ex.: "assinaturas exportadas mudaram? marque para revisão de semver"
Convenções que fazem isso funcionar bem:
- Uma preocupação por arquivo, com o nome da preocupação. Arquivos pequenos são lidos por inteiro; um
checklist.mdmonolítico é lido por cima. - Escreva as checagens como ações verificáveis ("rode X e confirme Y"), não como aspirações ("o código deve ser seguro").
- Diga o gatilho logo no começo — a quais caminhos ou tipos de mudança a lista se aplica — para que um agente (ou uma pessoa) possa pular barato as que não interessam.
- Mantenha-as no controle de versão ao lado do código que elas guardam: assim evoluem junto com a base de código, e um PR que muda as regras muda a lista no mesmo diff.
Quando você pedir ao Hermes para revisar um PR em um repositório que tem .agents/checks/, diga a ele (ou ensine por uma skill) para ler primeiro as listas relevantes e relatar em relação a elas. Isso dá aos agentes de revisão o critério específico do projeto que os prompts genéricos de revisão deixam passar.
Relatar problemas
- Use as GitHub Issues
- Inclua: sistema operacional, versão do Python, versão do Hermes (
hermes --version), traceback completo do erro - Inclua os passos para reproduzir
- Confira as issues existentes antes de criar duplicatas
- Para vulnerabilidades de segurança, relate em privado, por favor
Comunidade
- Discord: discord.gg/NousResearch
- GitHub Discussions: para propostas de projeto e discussões de arquitetura
- Skills Hub: publique skills especializadas e compartilhe com a comunidade
Licença
Ao contribuir, você concorda que as suas contribuições serão licenciadas sob a Licença MIT.