본문으로 건너뛰기

기여

anchor alias

기여

헤르메스 에이전트에 기여해 주셔서 감사합니다! 이 가이드에서는 개발 환경 설정, 코드베이스 이해 및 PR 병합에 대해 다룹니다.

기여 우선순위

우리는 다음 순서로 기여를 평가합니다.

  1. 버그 수정 — 충돌, 잘못된 동작, 데이터 손실
  2. 교차 플랫폼 호환성 — macOS, 다양한 Linux 배포판, WSL2
  3. 보안 강화 — 셸 주입, 프롬프트 주입, 경로 탐색
  4. 성능 및 견고성 — 재시도 논리, 오류 처리, 점진적 성능 저하
  5. 새로운 기술 - 광범위하게 유용한 기술(기술 만들기 참조)
  6. 새로운 도구 — 거의 필요하지 않습니다. 대부분의 능력은 기술이어야 한다
  7. 문서 — 수정 사항, 설명, 새로운 예

일반적인 기여 경로

  • Hermes 코어를 수정하지 않고 사용자 정의/로컬 도구를 구축하시겠습니까? Hermes 플러그인 빌드로 시작하세요.
  • Hermes 자체를 위한 새로운 내장 핵심 도구를 구축하시겠습니까? 도구 추가로 시작하세요.
  • 새로운 기술을 쌓고 싶으신가요? 스킬 만들기로 시작하세요
  • 새로운 추론 제공자를 구축하시겠습니까? 공급자 추가로 시작하세요.

개발 설정

전제 조건

요구 사항메모
기트--recurse-submodules 지원 및 git-lfs 확장 설치
파이썬 3.11+누락된 경우 uv가 설치합니다.
uv빠른 Python 패키지 관리자(설치)
Node.js 20+선택 사항 - 브라우저 도구 및 WhatsApp 브리지에 필요합니다(루트 package.json 엔진과 일치).

복제 및 설치

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]"

# 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_constantsget_hermes_home()을 사용하고 사용자에게 표시되는 메시지에는 display_hermes_home()을 사용하세요. 전체 규칙은 AGENTS.md를 참조하세요.

플랫폼 간 호환성

Hermes는 공식적으로 **Linux, macOS, WSL2 및 기본 Windows(초기 베타 - PowerShell 설치를 통해)**를 지원합니다. 기본 Windows에서는 쉘 명령에 Git Bash(Git for Windows)를 사용합니다. 몇 가지 기능에는 POSIX 커널 기본 요소가 필요하며 제한되어 있습니다. 대시보드의 내장형 PTY 터미널 창(/chat 탭)은 WSL2 전용입니다. 기본 Windows 경로는 새롭고 빠르게 이동합니다. Windows를 많이 사용하는 개발을 수행하는 경우 거친 가장자리에 부딪혀 수정해야 합니다.

코드를 제공할 때 다음 규칙을 염두에 두세요.

  • 보호되지 않은 signal.SIGKILL 참조를 추가하지 마세요. Windows에서는 정의되지 않습니다. gateway.status.terminate_pid(pid, force=True)(Windows에서는 taskkill /T /F, POSIX에서는 SIGKILL을 수행하는 중앙 집중식 기본 요소)을 통해 라우팅하거나 getattr(signal, "SIGKILL", signal.SIGTERM)으로 대체합니다.
  • os.kill(pid, 0) 프로브에서 ProcessLookupError과 함께 OSError을 잡으세요. Windows는 대신 이미 사라진 PID에 대해 OSError(WinError 87, "매개 변수가 잘못되었습니다")을 발생시킵니다. ProcessLookupError.
  • 터미널을 POSIX 의미 체계로 강제하지 마십시오. os.setsid, os.killpg, os.getpgid, os.fork은 모두 Windows에서 발생합니다. if sys.platform != "win32":로 게이트합니다. 또는 if os.name != "nt":.
  • 명시적인 encoding="utf-8"을 사용하여 파일을 엽니다. Windows의 Python 기본값은 라틴어가 아닌 텍스트에서 mojibake 또는 충돌이 발생하는 시스템 로케일(종종 cp1252)입니다.
  • pathlib.Path / os.path.join을 사용하십시오. /과 수동으로 연결하지 마십시오. 이것은 OS가 우리에게 돌려주는 문자열에 대해서는 덜 중요하고 우리가 하위 프로세스에 전달하기 위해 구성한 문자열에 대해서는 더 중요합니다.

주요 패턴:

1. termiosfcntl은 Unix 전용입니다.

항상 ImportErrorNotImplementedError을 모두 파악하세요.

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. 파일 인코딩

일부 환경에서는 .env 파일을 UTF-8이 아닌 인코딩으로 저장할 수 있습니다.

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을 사용하세요.

보안 고려 사항

헤르메스에는 터미널 액세스 권한이 있습니다. 보안이 중요합니다.

기존 보호

레이어구현
Sudo 비밀번호 파이핑shlex.quote()을 사용하여 쉘 주입을 방지합니다.
위험한 명령 감지사용자 승인 흐름이 포함된 tools/approval.py의 정규식 패턴
크론 프롬프트 주입스캐너는 명령 재정의 패턴을 차단합니다.
거부 목록 작성심볼릭 링크 우회를 방지하기 위해 os.path.realpath()을 통해 확인된 보호 경로
스킬 가드허브 설치 스킬에 대한 보안 스캐너
코드 실행 샌드박스API 키가 제거된 상태로 하위 프로세스가 실행됩니다.
컨테이너 경화Docker: 모든 기능 삭제, 권한 에스컬레이션 없음, PID 제한

보안에 민감한 코드 기여

  • 사용자 입력을 쉘 명령에 삽입할 때 항상 shlex.quote()을 사용하십시오.
  • 액세스 제어 확인 전에 os.path.realpath()을 사용하여 심볼릭 링크를 확인하세요.
  • 비밀을 기록하지 마세요
  • 도구 실행과 관련된 광범위한 예외를 포착하세요.
  • 변경 사항이 파일 경로나 프로세스에 영향을 미치는 경우 모든 플랫폼에서 테스트하세요.

풀 요청 프로세스

지점 이름 지정

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

제출하기 전에

  1. 테스트 실행: pytest tests/ -v
  2. 수동 테스트: hermes을 실행하고 변경한 코드 경로를 실행합니다.
  3. 플랫폼 간 영향 확인: macOS 및 다양한 Linux 배포판 고려
  4. PR에 집중하세요: PR당 하나의 논리적 변경

홍보설명

포함:

  • 변경된 사항이유
  • 테스트 방법
  • 테스트한 플랫폼
  • 관련 문제를 참조하세요.

커밋 메시지

우리는 기존 커밋을 사용합니다.

<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 문제 사용
  • 포함: OS, Python 버전, Hermes 버전(hermes version), 전체 오류 추적
  • 재현 단계 포함
  • 중복 항목을 만들기 전에 기존 문제를 확인하세요.
  • 보안취약점은 비공개로 신고해주세요

커뮤니티

  • 디스코드: discord.gg/NousResearch
  • GitHub 토론: 디자인 제안 및 아키텍처 토론
  • 기술 허브: 전문 기술을 업로드하고 커뮤니티와 공유

라이센스

기여함으로써 귀하는 귀하의 기여가 MIT 라이선스에 따라 라이선스가 부여된다는 데 동의하게 됩니다.