hermes-agent/CONTRIBUTING.es.md
e10552 2609bcccca feat(i18n): add complete Spanish translation
- Complete README.es.md (full Spanish translation of README)
- Add CONTRIBUTING.es.md (Spanish contributing guide)
- Add SECURITY.es.md (Spanish security policy)
- Fix remaining English strings in locales/es.yaml (resume Matrix section)
- Add Spanish badge to README.md

All 47 i18n tests pass, including catalog key parity and placeholder parity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 23:23:47 -07:00

29 KiB

Contribuir a Hermes Agent

¡Gracias por contribuir a Hermes Agent! Esta guía cubre todo lo que necesitas: configurar tu entorno de desarrollo, entender la arquitectura, decidir qué construir y conseguir que tu PR sea aceptado.


Prioridades de Contribución

Valoramos las contribuciones en este orden:

  1. Correcciones de errores — bloqueos, comportamiento incorrecto, pérdida de datos. Siempre la máxima prioridad.
  2. Compatibilidad entre plataformas — macOS, diferentes distribuciones de Linux y WSL2 en Windows. Queremos que Hermes funcione en todas partes.
  3. Fortalecimiento de seguridad — inyección de shell, inyección de prompts, traversal de rutas, escalada de privilegios. Ver Consideraciones de Seguridad.
  4. Rendimiento y robustez — lógica de reintento, manejo de errores, degradación elegante.
  5. Nuevas habilidades — pero solo las ampliamente útiles. Ver ¿Debería ser una Habilidad o una Herramienta?
  6. Nuevas herramientas — raramente necesarias. La mayoría de las capacidades deberían ser habilidades. Ver más abajo.
  7. Documentación — correcciones, aclaraciones, nuevos ejemplos.

¿Debería ser una Habilidad o una Herramienta?

Esta es la pregunta más común para los nuevos colaboradores. La respuesta casi siempre es habilidad.

Hazlo una Habilidad cuando:

  • La capacidad se puede expresar como instrucciones + comandos de shell + herramientas existentes
  • Envuelve una CLI externa o API que el agente puede llamar a través de terminal o web_extract
  • No necesita integración personalizada de Python ni gestión de claves API integrada en el agente
  • Ejemplos: búsqueda en arXiv, flujos de trabajo de git, gestión de Docker, procesamiento de PDF, email a través de herramientas CLI

Hazlo una Herramienta cuando:

  • Requiere integración de extremo a extremo con claves API, flujos de autenticación o configuración de múltiples componentes gestionada por el harness del agente
  • Necesita lógica de procesamiento personalizada que debe ejecutarse con precisión en cada ocasión (no "mejor esfuerzo" de la interpretación del LLM)
  • Maneja datos binarios, streaming o eventos en tiempo real que no pueden pasar por el terminal
  • Ejemplos: automatización de navegador (gestión de sesiones Browserbase), TTS (codificación de audio + entrega en plataforma), análisis de visión (manejo de imágenes base64)

¿Debería la Habilidad estar incluida?

Las habilidades incluidas (en skills/) se envían con cada instalación de Hermes. Deben ser ampliamente útiles para la mayoría de los usuarios:

  • Manejo de documentos, investigación web, flujos de trabajo de desarrollo comunes, administración de sistemas
  • Usadas regularmente por una amplia gama de personas

Si tu habilidad es oficial y útil pero no universalmente necesaria (ej., una integración de servicio de pago, una dependencia pesada), ponla en optional-skills/ — se envía con el repositorio pero no está activada por defecto. Los usuarios pueden descubrirla a través de hermes skills browse (etiquetada como "oficial") e instalarla con hermes skills install (sin advertencia de terceros, confianza integrada).

Si tu habilidad es especializada, contribuida por la comunidad o de nicho, es mejor para un Skills Hub — súbela a un registro de habilidades y compártela en el Discord de Nous Research. Los usuarios pueden instalarla con hermes skills install.


Proveedores de Memoria: Publicar como Plugin Independiente

Ya no aceptamos nuevos proveedores de memoria en este repositorio. El conjunto de proveedores integrados en plugins/memory/ (honcho, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb) está cerrado. Si quieres añadir un nuevo backend de memoria, publícalo como un repositorio de plugin independiente que los usuarios instalen en ~/.hermes/plugins/ (o a través de un entry point de pip).

Los plugins de memoria independientes:

  • Implementan el mismo ABC MemoryProvider (agent/memory_provider.py) — sync_turn, prefetch, shutdown y opcionalmente post_setup(hermes_home, config) para integración con el asistente de configuración
  • Usan el mismo sistema de descubrimiento — discover_memory_providers() los recoge desde directorios de plugins de usuario/proyecto y entry points de pip
  • Se integran con hermes memory setup a través de post_setup() — sin necesidad de tocar el código base
  • Pueden registrar sus propios subcomandos CLI a través de register_cli(subparser) en un archivo cli.py
  • Obtienen todos los mismos hooks de ciclo de vida y plomería de configuración que los proveedores incluidos en el árbol

Los PRs que añadan un nuevo directorio bajo plugins/memory/ serán cerrados con un puntero para publicar el proveedor como su propio repositorio. Los proveedores en árbol existentes se mantienen; las correcciones de errores para ellos son bienvenidas.

Esto no es una barra de calidad — es una decisión de acoplamiento y mantenimiento. Los proveedores de memoria son el tipo de plugin más común y no deberían vivir todos en este árbol.


Configuración del Desarrollo

Prerequisitos

Requisito Notas
Git Con la extensión git-lfs instalada
Python 3.11+ uv lo instalará si falta
uv Gestor de paquetes Python rápido (instalar)
Node.js 20+ Opcional — necesario para herramientas de navegador y puente WhatsApp (coincide con los engines de package.json raíz)

Clonar e instalar

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

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

# Instalar con todos los extras (mensajería, cron, menús CLI, herramientas de desarrollo)
uv pip install -e ".[all,dev]"

# Opcional: herramientas de navegador
npm install

Configurar para desarrollo

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

# Añadir al menos una clave de proveedor LLM:
echo "OPENROUTER_API_KEY=***" >> ~/.hermes/.env

Ejecutar

# Enlace simbólico para acceso global
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

# Verificar
hermes doctor
hermes chat -q "Hola"

Ejecutar tests

# Preferido — coincide con CI (entorno hermético, 4 workers xdist); ver AGENTS.md
scripts/run_tests.sh

# Alternativa (activa el venv primero). El wrapper sigue recomendándose
# para paridad con GitHub Actions antes de abrir un PR:
pytest tests/ -v

Estructura del Proyecto

hermes-agent/
├── run_agent.py              # Clase AIAgent — bucle de conversación central, despacho de herramientas, persistencia de sesión
├── cli.py                    # Clase HermesCLI — TUI interactiva, integración prompt_toolkit
├── model_tools.py            # Orquestación de herramientas (capa delgada sobre tools/registry.py)
├── toolsets.py               # Agrupaciones y presets de herramientas (hermes-cli, hermes-telegram, etc.)
├── hermes_state.py           # Base de datos de sesiones SQLite con búsqueda de texto completo FTS5, títulos de sesión
├── batch_runner.py           # Procesamiento en lote paralelo para generación de trayectorias
│
├── agent/                    # Internos del agente (módulos extraídos)
│   ├── prompt_builder.py         # Ensamblaje del prompt del sistema (identidad, habilidades, archivos de contexto, memoria)
│   ├── context_compressor.py     # Auto-resumición al acercarse a los límites de contexto
│   ├── auxiliary_client.py       # Resuelve clientes OpenAI auxiliares (resumición, visión)
│   ├── display.py                # KawaiiSpinner, formateo del progreso de herramientas
│   ├── model_metadata.py         # Longitudes de contexto del modelo, estimación de tokens
│   └── trajectory.py             # Ayudantes para guardar trayectorias
│
├── hermes_cli/               # Implementaciones de comandos CLI
│   ├── main.py                   # Punto de entrada, análisis de argumentos, despacho de comandos
│   ├── config.py                 # Gestión de configuración, migración, definiciones de variables de entorno
│   ├── setup.py                  # Asistente de configuración interactivo
│   ├── auth.py                   # Resolución de proveedor, OAuth, Nous Portal
│   ├── models.py                 # Listas de selección de modelos de OpenRouter
│   ├── banner.py                 # Banner de bienvenida, arte ASCII
│   ├── commands.py               # Registro central de comandos de barra (CommandDef), autocompletado, ayudantes del gateway
│   ├── callbacks.py              # Callbacks interactivos (aclarar, sudo, aprobación)
│   ├── doctor.py                 # Diagnósticos
│   ├── skills_hub.py             # CLI del Skills Hub + comando de barra /skills
│   └── skin_engine.py            # Motor de skins/temas — personalización visual de CLI basada en datos
│
├── tools/                    # Implementaciones de herramientas (auto-registradas)
│   ├── registry.py               # Registro central de herramientas (esquemas, manejadores, despacho)
│   ├── approval.py               # Detección de comandos peligrosos + aprobación por sesión
│   ├── terminal_tool.py          # Orquestación del terminal (sudo, ciclo de vida del entorno, backends)
│   ├── file_operations.py        # read_file, write_file, búsqueda, patch, etc.
│   ├── web_tools.py              # web_search, web_extract (Paralelo/Firecrawl + resumición Gemini)
│   ├── vision_tools.py           # Análisis de imágenes a través de modelos multimodales
│   ├── delegate_tool.py          # Lanzamiento de subagentes y ejecución paralela de tareas
│   ├── code_execution_tool.py    # Python sandboxado con acceso a herramientas vía RPC
│   ├── session_search_tool.py    # Búsqueda en conversaciones pasadas con FTS5 + ventanas ancladas
│   ├── cronjob_tools.py          # Gestión de tareas programadas
│   ├── skill_tools.py            # Búsqueda, carga y gestión de habilidades
│   └── environments/             # Backends de ejecución del terminal
│       ├── base.py                   # ABC BaseEnvironment
│       ├── local.py, docker.py, ssh.py, singularity.py, modal.py, daytona.py
│
├── gateway/                  # Gateway de mensajería
│   ├── run.py                    # GatewayRunner — ciclo de vida de plataformas, enrutamiento de mensajes, cron
│   ├── config.py                 # Resolución de configuración de plataformas
│   ├── session.py                # Almacén de sesiones, prompts de contexto, políticas de reset
│   └── platforms/                # Adaptadores de plataformas
│       ├── telegram.py, discord_adapter.py, slack.py, whatsapp.py
│
├── scripts/                  # Scripts del instalador y puente
│   ├── install.sh                # Instalador Linux/macOS
│   ├── install.ps1               # Instalador Windows PowerShell
│   └── whatsapp-bridge/          # Puente WhatsApp Node.js (Baileys)
│
├── skills/                   # Habilidades incluidas (copiadas a ~/.hermes/skills/ en la instalación)
├── optional-skills/          # Habilidades opcionales oficiales (descubribles vía hub, no activadas por defecto)
├── tests/                    # Suite de tests
├── website/                  # Sitio de documentación (hermes-agent.nousresearch.com)
│
├── cli-config.yaml.example   # Configuración de ejemplo (copiada a ~/.hermes/config.yaml)
└── AGENTS.md                 # Guía de desarrollo para asistentes de codificación IA

Configuración del usuario (almacenada en ~/.hermes/)

Ruta Propósito
~/.hermes/config.yaml Configuración (modelo, terminal, toolsets, compresión, etc.)
~/.hermes/.env Claves API y secretos
~/.hermes/auth.json Credenciales OAuth (Nous Portal)
~/.hermes/skills/ Todas las habilidades activas (incluidas + instaladas desde hub + creadas por el agente)
~/.hermes/memories/ Memoria persistente (MEMORY.md, USER.md)
~/.hermes/state.db Base de datos de sesiones SQLite
~/.hermes/sessions/ Índice de enrutamiento del gateway (sessions.json), migas de pan de solicitudes, transcripciones *.jsonl del gateway y (opcionalmente) snapshots JSON por sesión cuando sessions.write_json_snapshots: true está configurado. Los snapshots por sesión están desactivados por defecto; state.db es canónica.
~/.hermes/cron/ Datos de trabajos programados
~/.hermes/whatsapp/session/ Credenciales del puente WhatsApp

Descripción General de la Arquitectura

Bucle Central

Mensaje del usuario → AIAgent._run_agent_loop()
  ├── Construir prompt del sistema (prompt_builder.py)
  ├── Construir kwargs de API (modelo, mensajes, herramientas, configuración de razonamiento)
  ├── Llamar al LLM (API compatible con OpenAI)
  ├── Si tool_calls en la respuesta:
  │     ├── Ejecutar cada herramienta a través del despacho del registro
  │     ├── Añadir resultados de herramientas a la conversación
  │     └── Volver a la llamada al LLM
  ├── Si respuesta de texto:
  │     ├── Persistir sesión en DB
  │     └── Devolver final_response
  └── Compresión de contexto si se acerca al límite de tokens

Patrones de Diseño Clave

  • Herramientas auto-registradas: Cada archivo de herramienta llama a registry.register() en el momento de importación. model_tools.py activa el descubrimiento importando todos los módulos de herramientas.
  • Agrupación en toolsets: Las herramientas se agrupan en toolsets (web, terminal, file, browser, etc.) que pueden habilitarse/deshabilitarse por plataforma.
  • Persistencia de sesión: Todas las conversaciones se almacenan en SQLite (hermes_state.py) con búsqueda de texto completo y títulos de sesión únicos.
  • Inyección efímera: Los prompts del sistema y los mensajes de relleno se inyectan en el momento de la llamada API, nunca se persisten en la base de datos ni en los logs.
  • Abstracción de proveedor: El agente funciona con cualquier API compatible con OpenAI. La resolución del proveedor ocurre en el momento de la inicialización.
  • Enrutamiento de proveedor: Al usar OpenRouter, provider_routing en config.yaml controla la selección del proveedor.

Estilo de Código

  • PEP 8 con excepciones prácticas (no imponemos longitud de línea estricta)
  • Comentarios: Solo cuando se explica la intención no obvia, compromisos o peculiaridades de API. No narres lo que hace el código
  • Manejo de errores: Captura excepciones específicas. Registra con logger.warning()/logger.error() — usa exc_info=True para errores inesperados
  • Multiplataforma: Nunca asumas Unix. Ver Compatibilidad Multiplataforma

Añadir una Nueva Herramienta

Antes de escribir una herramienta, pregúntate: ¿debería ser una habilidad en su lugar?

Las herramientas se auto-registran en el registro central. Cada archivo de herramienta co-localiza su esquema, manejador y registro:

"""my_tool — Breve descripción de lo que hace esta herramienta."""

import json
from tools.registry import registry


def my_tool(param1: str, param2: int = 10, **kwargs) -> str:
    """Manejador. Devuelve un resultado en cadena (a menudo JSON)."""
    result = do_work(param1, param2)
    return json.dumps(result)


MY_TOOL_SCHEMA = {
    "type": "function",
    "function": {
        "name": "my_tool",
        "description": "Qué hace esta herramienta y cuándo debería usarla el agente.",
        "parameters": {
            "type": "object",
            "properties": {
                "param1": {"type": "string", "description": "Qué es param1"},
                "param2": {"type": "integer", "description": "Qué es param2", "default": 10},
            },
            "required": ["param1"],
        },
    },
}


def _check_requirements() -> bool:
    """Devuelve True si las dependencias de esta herramienta están disponibles."""
    return True


registry.register(
    name="my_tool",
    toolset="my_toolset",
    schema=MY_TOOL_SCHEMA,
    handler=lambda args, **kw: my_tool(**args, **kw),
    check_fn=_check_requirements,
)

Conectar a un toolset (requerido): Las herramientas integradas se auto-descubren: cualquier archivo tools/*.py que contenga una llamada de nivel superior registry.register(...) es importado por discover_builtin_tools() en tools/registry.py cuando model_tools se carga. No hay una lista de importaciones manual en model_tools.py que mantener.

Todavía debes añadir el nombre de la herramienta a la lista apropiada en toolsets.py (por ejemplo _HERMES_CORE_TOOLS o un toolset dedicado); de lo contrario la herramienta se registra pero nunca se expone al agente.

Consulta AGENTS.md (sección Adding New Tools) para rutas conscientes del perfil y orientación sobre plugins vs. núcleo.


Añadir una Habilidad

Las habilidades incluidas viven en skills/ organizadas por categoría. Las habilidades opcionales oficiales usan la misma estructura en optional-skills/:

skills/
├── research/
│   └── arxiv/
│       ├── SKILL.md              # Requerido: instrucciones principales
│       └── scripts/              # Opcional: scripts auxiliares
│           └── search_arxiv.py
├── productivity/
│   └── ocr-and-documents/
│       ├── SKILL.md
│       ├── scripts/
│       └── references/
└── ...

Formato de SKILL.md

---
name: my-skill
description: Breve descripción (mostrada en los resultados de búsqueda de habilidades)
version: 1.0.0
author: Tu Nombre
license: MIT
platforms: [macos, linux]          # Opcional — restringir a plataformas de SO específicas
required_environment_variables:    # Opcional — metadatos de configuración segura al cargar
  - name: MY_API_KEY
    prompt: Clave API
    help: Dónde obtenerla
    required_for: funcionalidad completa
prerequisites:                     # Requisitos de tiempo de ejecución heredados opcionales
  env_vars: [MY_API_KEY]
  commands: [curl, jq]
metadata:
  hermes:
    tags: [Categoría, Subcategoría, Palabras clave]
    related_skills: [other-skill-name]
    fallback_for_toolsets: [web]
    requires_toolsets: [terminal]
---

# Título de la Habilidad

Introducción breve.

## Cuándo Usar
Condiciones de activación — ¿cuándo debería el agente cargar esta habilidad?

## Referencia Rápida
Tabla de comandos o llamadas API comunes.

## Procedimiento
Instrucciones paso a paso que el agente sigue.

## Problemas Conocidos
Modos de fallo conocidos y cómo manejarlos.

## Verificación
Cómo confirma el agente que funcionó.

Estándares de autoría de habilidades (OBLIGATORIOS)

Todo skill nuevo o modernizado — incluido, opcional o contribuido — debe cumplir estos estándares antes del merge:

  1. description ≤ 60 caracteres, una oración, termina con punto. Las descripciones largas saturan la UI de listado de habilidades. Indica la capacidad, no la implementación. Sin palabras de marketing ("potente", "completo", "fluido", "avanzado").

  2. Las herramientas referenciadas en el cuerpo de SKILL.md deben ser herramientas nativas de Hermes o servidores MCP que la habilidad espere explícitamente. Usa los nombres de herramientas en comillas invertidas: `terminal`, `web_extract`, `web_search`, `read_file`, `write_file`, etc.

  3. El campo platforms: auditado contra las importaciones reales del script. Las habilidades que usen primitivos solo de POSIX deben declarar sus plataformas soportadas.

  4. author da crédito primero al colaborador humano.

  5. El cuerpo de SKILL.md usa el orden moderno de secciones: título, intro de 2-3 oraciones, luego: ## Cuándo Usar, ## Prerequisitos, ## Cómo Ejecutar, ## Referencia Rápida, ## Procedimiento, ## Problemas Conocidos, ## Verificación.

  6. Los scripts van en scripts/, las referencias en references/, las plantillas en templates/.

  7. Los tests viven en tests/skills/test_<skill>_skill.py y usan solo stdlib + pytest + unittest.mock. Sin llamadas de red en vivo.

  8. Las adiciones a .env.example están aisladas en un bloque claramente delimitado.


Añadir una Skin / Tema

Hermes usa un sistema de skins basado en datos — no se necesitan cambios de código para añadir una nueva skin.

Opción A: Skin de usuario (archivo YAML)

Crea ~/.hermes/skins/<nombre>.yaml:

name: mitema
description: Breve descripción del tema

colors:
  banner_border: "#HEX"
  banner_title: "#HEX"
  banner_accent: "#HEX"
  banner_dim: "#HEX"
  banner_text: "#HEX"
  response_border: "#HEX"

spinner:
  waiting_faces: ["(⚔)", "(⛨)"]
  thinking_faces: ["(⚔)", "(⌁)"]
  thinking_verbs: ["forjando", "planeando"]

branding:
  agent_name: "Mi Agente"
  welcome: "Mensaje de bienvenida"
  response_label: " ⚔ Agente "
  prompt_symbol: "⚔"

tool_prefix: "╎"

Todos los campos son opcionales — los valores faltantes se heredan de la skin predeterminada.

Opción B: Skin integrada

Añade al dict _BUILTIN_SKINS en hermes_cli/skin_engine.py. Usa el mismo esquema que arriba pero como dict de Python.

Activar:

  • CLI: /skin mitema o establece display.skin: mitema en config.yaml

Compatibilidad Multiplataforma

Hermes se ejecuta en Linux, macOS y Windows nativo (además de WSL2). Al escribir código que toca el SO, asume que cualquier plataforma puede alcanzar tu ruta de código.

Antes de hacer PR: ejecuta scripts/check-windows-footguns.py para detectar los patrones inseguros comunes de Windows en tu diff. Es basado en grep y barato; CI también lo ejecuta en cada PR.

Reglas críticas

  1. Nunca llames os.kill(pid, 0) para comprobaciones de liveness. En Windows NO es una operación sin efecto. Usa psutil.pid_exists(pid) en su lugar.

  2. Usa shutil.which() antes de hacer shell — no asumas que Windows tiene las herramientas que tiene Linux. ps, kill, grep, awk, etc. simplemente no existen en Windows.

  3. termios y fcntl son solo de Unix. Siempre captura tanto ImportError como NotImplementedError.

  4. Codificación de archivos. Windows puede guardar archivos .env en cp1252. Siempre maneja errores de codificación.

  5. Gestión de procesos. os.setsid(), os.killpg(), os.fork(), os.getuid() y el manejo de señales POSIX difieren en Windows.

  6. Señales que no existen en Windows: SIGALRM, SIGCHLD, SIGHUP, SIGUSR1, SIGUSR2, etc.

  7. Separadores de ruta. Usa pathlib.Path en lugar de concatenación de cadenas con /.

  8. Los enlaces simbólicos necesitan privilegios elevados en Windows (a menos que el Modo Desarrollador esté activado).

  9. Los modos de archivo POSIX (0o600, 0o644, etc.) NO se aplican en NTFS por defecto.

  10. Los daemons de fondo desacoplados en Windows necesitan pythonw.exe, NO python.exe.


Consideraciones de Seguridad

Hermes tiene acceso al terminal. La seguridad importa.

Protecciones existentes

Capa Implementación
Piping de contraseña sudo Usa shlex.quote() para prevenir inyección de shell
Detección de comandos peligrosos Patrones regex en tools/approval.py con flujo de aprobación del usuario
Inyección de prompts en cron Escáner en tools/cronjob_tools.py bloquea patrones de anulación de instrucciones
Lista de denegación de escritura Rutas protegidas resueltas a través de os.path.realpath() para prevenir bypass de enlaces simbólicos
Skills Guard Escáner de seguridad para habilidades instaladas desde el hub (tools/skills_guard.py)
Sandbox de ejecución de código El proceso hijo execute_code se ejecuta con claves API eliminadas del entorno
Fortalecimiento de contenedor Docker: todas las capacidades eliminadas, sin escalada de privilegios, límites de PID, tmpfs de tamaño limitado

Al contribuir código sensible a la seguridad

  • Siempre usa shlex.quote() al interpolar entrada del usuario en comandos de shell
  • Resuelve enlaces simbólicos con os.path.realpath() antes de comprobaciones de control de acceso basadas en rutas
  • No registres secretos. Las claves API, tokens y contraseñas nunca deben aparecer en la salida de log
  • Captura excepciones amplias alrededor de la ejecución de herramientas para que un solo fallo no bloquee el bucle del agente
  • Prueba en todas las plataformas si tu cambio toca rutas de archivos, gestión de procesos o comandos de shell

Política de fijación de dependencias (fortalecimiento de la cadena de suministro)

Tras el compromiso de la cadena de suministro de litellm en marzo de 2026 y la campaña del gusano Mini Shai-Hulud en mayo de 2026, todas las dependencias deben seguir estas reglas:

Tipo de fuente Tratamiento requerido Justificación
Paquete PyPI >=suelo,<siguiente_mayor Las versiones de PyPI son inmutables una vez publicadas, pero pueden empujarse nuevas versiones en tu rango.
URL de Git SHA completo del commit Las ramas y etiquetas son refs mutables; el SHA está direccionado por contenido.
GitHub Actions SHA completo del commit + comentario de versión Las etiquetas de acción son refs mutables. Fija como uses: owner/action@<sha> # vX.Y.Z
Instalaciones pip solo de CI ==exacto Builds de CI herméticos; el cambio es aceptable.

Cada nueva dependencia de PyPI en un PR debe tener un límite superior <siguiente_mayor. Los PRs que añadan especificaciones >=X.Y.Z sin límite superior serán rechazados.


Proceso de Pull Request

Nomenclatura de ramas

fix/descripcion        # Correcciones de errores
feat/descripcion       # Nuevas funcionalidades
docs/descripcion       # Documentación
test/descripcion       # Tests
refactor/descripcion   # Reestructuración de código

Antes de enviar

  1. Ejecutar tests: scripts/run_tests.sh (recomendado; igual que CI) o pytest tests/ -v con el venv del proyecto activado
  2. Probar manualmente: Ejecuta hermes y ejercita la ruta de código que cambiaste
  3. Verificar impacto multiplataforma: Si tocas E/S de archivos, gestión de procesos o manejo del terminal, considera macOS, Linux y WSL2
  4. Mantén los PRs enfocados: Un cambio lógico por PR. No mezcles una corrección de error con una refactorización con una nueva funcionalidad.

Descripción del PR

Incluye:

  • Qué cambió y por qué
  • Cómo probarlo (pasos de reproducción para errores, ejemplos de uso para funcionalidades)
  • Qué plataformas probaste
  • Referencia cualquier issue relacionado

Mensajes de commit

Usamos Conventional Commits:

<tipo>(<alcance>): <descripción>
Tipo Usar para
fix Correcciones de errores
feat Nuevas funcionalidades
docs Documentación
test Tests
refactor Reestructuración de código (sin cambio de comportamiento)
chore Build, CI, actualizaciones de dependencias

Alcances: cli, gateway, tools, skills, agent, install, whatsapp, security, etc.

Ejemplos:

fix(cli): prevenir bloqueo en save_config_value cuando el modelo es una cadena
feat(gateway): añadir aislamiento de sesión multi-usuario de WhatsApp
fix(security): prevenir inyección de shell en el piping de contraseña sudo
test(tools): añadir tests unitarios para file_operations

Reportar Issues

  • Usa GitHub Issues
  • Incluye: SO, versión de Python, versión de Hermes (hermes version), traza de error completa
  • Incluye pasos para reproducir
  • Verifica los issues existentes antes de crear duplicados
  • Para vulnerabilidades de seguridad, por favor reporta de forma privada

Comunidad

  • Discord: discord.gg/NousResearch — para preguntas, mostrar proyectos y compartir habilidades
  • GitHub Discussions: Para propuestas de diseño y discusiones de arquitectura
  • Skills Hub: Sube habilidades especializadas a un registro y compártelas con la comunidad

Licencia

Al contribuir, aceptas que tus contribuciones serán licenciadas bajo la Licencia MIT.