# CLAUDE.md — Contexto del proyecto agents_and_robots ## Qué es este proyecto Monorepo en Go para gestionar bots Matrix. Cada bot es un agente autónomo con personalidad, reglas de decisión y acceso a herramientas (LLM, SSH, HTTP, MCP). Los bots se comunican entre sí y con humanos a través de Matrix (mautrix-go). **Homeserver activo:** `https://matrix-af2f3d.organic-machine.com` **Server name:** `matrix-af2f3d.organic-machine.com` ## Filosofía de diseño — LA REGLA MÁS IMPORTANTE El proyecto usa el patrón **pure core / impure shell** estrictamente: ``` pkg/ → PURE: solo tipos, funciones puras, cero side effects shell/ → IMPURE: todo I/O, red, filesystem, procesos agents/ → composición: reglas puras + ensamblado con shell en runtime.go ``` **Nunca** añadir side effects (I/O, red, llamadas a APIs) dentro de `pkg/`. **Siempre** que el core necesite "hacer algo", produce un `[]decision.Action` (datos puros) que el shell interpreta. El flujo es siempre: ``` Matrix event → Parse (pure) → Evaluate rules (pure) → []Action (pure data) → Runner.Execute (impure) → efectos reales ``` ## Módulo Go `github.com/enmanuel/agents` ## Estructura de directorios ``` pkg/decision/ → motor de reglas puro (Evaluate, Rule, MatchFunc, Action) pkg/llm/ → tipos de LLM puros (CompleteFunc, CompletionRequest, Route) pkg/tools/ → specs declarativas de herramientas (SSHCommandSpec, etc.) pkg/message/ → parse y format de mensajes Matrix (puros) pkg/personality/ → tipos de personalidad (Personality, Tone, etc.) shell/llm/ → clientes LLM reales (anthropic.go, openai.go, factory.go) shell/matrix/ → cliente Matrix mautrix-go (client.go, listener.go) shell/ssh/ → ejecutor SSH real (executor.go) shell/effects/ → Runner que interpreta []Action → side effects shell/bus/ → comunicación inter-agente via Go channels shell/protocols/ → adaptadores MCP (mcp.go) agents/runtime.go → Agent{}: ensambla core + shell, maneja eventos agents/assistant-bot/ → reglas puras + config del assistant-bot internal/config/schema.go → tipos completos del YAML de configuración internal/config/loader.go → Load() con expand env vars, LoadMeta() sin validación cmd/launcher/main.go → inicia agentes, tiene rulesRegistry cmd/agentctl/main.go → CLI de gestión (list, start, stop, remove) cmd/register/main.go → registra bots en Synapse via admin API dev-scripts/ → scripts bash para operaciones del día a día dev-scripts/server/ → gestión del launcher (start, stop, restart, ps, logs, dashboard) dev-scripts/agent/ → gestión de agentes (new, register, verify, avatar, remove, list) ``` ## Reglas para LLMs Las reglas guían cómo ejecutar tareas específicas respetando la arquitectura del proyecto. Ver índice completo en `.claude/rules/index.md`. | Regla | Cuándo aplicarla | |-------|------------------| | `.claude/rules/create_agent.md` | Al crear un nuevo bot/agente Matrix | | `.claude/rules/create_tool.md` | Al añadir una nueva tool para function calling | | `.claude/rules/create_command.md` | Al añadir un comando directo (!xxx) a un agente | | `.claude/rules/create_issue.md` | Al crear un nuevo issue en `dev/issues/` | | `.claude/rules/fix_issue.md` | Al implementar/arreglar un issue existente | Documentación detallada para humanos en `docs/creating-agents.md`. ## Agentes existentes | ID | Estado | LLM | Descripción | |----------------|-----------|---------|------------------------------------------| | assistant-bot | activo | GPT-4o | Asistente general, responde DMs | | asistente-2 | activo | GPT-4o | Asistente con tools (current_time) | ## Dependencias clave ``` maunium.net/go/mautrix v0.21.1 → Matrix client github.com/sashabaranov/go-openai → OpenAI + Ollama-compatible github.com/mark3labs/mcp-go → MCP protocol server/client golang.org/x/crypto/ssh → SSH execution github.com/spf13/cobra → CLI gopkg.in/yaml.v3 → Config parsing ``` ## Configuración de agentes Cada agente vive en `agents//`: - `config.yaml` — configuración completa (ver schema en `internal/config/schema.go`) - `agent.go` — reglas puras que implementan `Rules() []decision.Rule` - `prompts/system.md` — system prompt del LLM - `data/` — datos de runtime (SQLite, crypto, logs) — en .gitignore El `config.yaml` soporta variables de entorno con `${VAR}` y `$VAR`. El loader usa `os.ExpandEnv`. Secciones principales del config: `agent`, `personality`, `llm`, `tools`, `matrix`, `agents` (peers), `ssh`, `security`, `schedules`, `observability`, `resilience`, `storage`. ## Cómo añadir un nuevo bot Guía rápida (detalle completo en `docs/creating-agents.md`, regla en `.claude/rules/create_agent.md`): 1. Crear scaffold: `./dev-scripts/agent/new-agent.sh "Display Name"` o manual en `agents//` 2. Crear `agent.go` (reglas puras), `config.yaml`, `prompts/system.md` 3. Registrar en `cmd/launcher/main.go` → import + `rulesRegistry` 4. Registrar en Matrix: `./dev-scripts/agent/register.sh "Display Name"` 5. Avatar y nombre: `./dev-scripts/agent/avatar.sh static/.jpg` 6. Verificación E2EE: `go run -tags goolm ./cmd/verify --homeserver ... --username --password ... --token ...` 7. Arrancar: `./dev-scripts/server/start.sh ` ## Dev-scripts disponibles ```bash # === server/ — gestión del launcher === ./dev-scripts/server/start.sh # iniciar el launcher ./dev-scripts/server/stop.sh # detener el launcher ./dev-scripts/server/restart.sh # reiniciar el launcher ./dev-scripts/server/ps.sh # procesos con detalle (PID, mem, CPU, uptime) ./dev-scripts/server/logs.sh [lines] # tail -f de logs ./dev-scripts/server/dashboard.sh # TUI interactiva # Gestión unificada (wrapper) ./dev-scripts/server/server.sh start # iniciar ./dev-scripts/server/server.sh stop # detener ./dev-scripts/server/server.sh restart # reiniciar ./dev-scripts/server/server.sh status # resumen general del servidor ./dev-scripts/server/server.sh ps # procesos con detalle ./dev-scripts/server/server.sh logs # tail -f de logs ./dev-scripts/server/server.sh kill # SIGKILL forzado (emergencia) # === agent/ — gestión de agentes === ./dev-scripts/agent/list.sh # ver todos los bots y estado ./dev-scripts/agent/new-agent.sh [name] # scaffold completo ./dev-scripts/agent/register.sh [name] # registrar bot en Matrix ./dev-scripts/agent/verify.sh [agent-id] # verificación E2EE ./dev-scripts/agent/avatar.sh # subir avatar ./dev-scripts/agent/reset-password.sh # resetear password ./dev-scripts/agent/remove.sh # deshabilitar (sin borrar datos) ``` PID files: `run/.pid` | Log files: `run/.log` ## Gestión de procesos Los bots corren como procesos independientes lanzados por `agentctl` o `dev-scripts/server/start.sh`. Cada proceso escribe su PID en `run/.pid` y su log en `run/.log`. `is_running()` usa `kill -0 ` para verificar sin matar el proceso. ## Variables de entorno críticas ```bash MATRIX_HOMESERVER # URL del servidor Matrix MATRIX_SERVER_NAME # nombre del servidor (parte después de :) MATRIX_ADMIN_TOKEN # token admin para registrar bots (cmd/register) MATRIX_TOKEN_ # access token de cada bot OPENAI_API_KEY # OpenAI ANTHROPIC_API_KEY # Anthropic/Claude ``` Nunca commitear `.env`. Plantilla en `.env.example`. ## Trunk-based development (TBD) El proyecto usa trunk-based development estricto. **master** es el único branch estable y siempre deployable. ### Flujo de trabajo ``` master (trunk) ← siempre deployable, único branch permanente ↑ └── issue/- ← rama efímera (horas, no días) ├── commit: feat: ... ├── commit: test: ... └── commit: docs: ... merge --no-ff → master → push → delete branch ``` 1. **`/git-branch`** — crea rama `issue/-` desde master actualizado 2. Implementar en la rama con commits granulares por bloque lógico 3. **`/git-push`** — tests → merge `--no-ff` a master → push → eliminar rama ### Convención de commits Dentro de la rama, cada commit es **atómico por bloque lógico** (no mezclar feat + test en uno): | Prefijo | Uso | |---------|-----| | `feat:` | nueva funcionalidad | | `fix:` | corrección de error | | `refactor:` | cambio estructural sin cambio funcional | | `docs:` | documentación | | `chore:` | mantenimiento | | `test:` | tests nuevos o modificados | | `merge:` | commit de merge (generado por `--no-ff`) | - **Título** (`-m` corto): resumen del bloque - **Cuerpo** (`-m` largo): en español, explica qué, por qué, impacto y alcance - **No hacer commits WIP**: nada de "wip", "tmp", "fix fix" — cada commit debe tener mensaje real - **No squash**: `--no-ff` preserva los commits individuales; `git log --first-parent master` da la vista limpia (un merge = un issue) ### Reglas de ramas - **Nunca trabajar directamente en master** — siempre crear rama con `/git-branch` - **Una rama por issue** — no mezclar issues en la misma rama - **Ramas cortas** — idealmente horas, no días - **Nunca pushear la rama** — solo se pushea master después del merge - **No rebase interactivo** — si los commits ya son limpios, no hay nada que reescribir ### Feature flags — features grandes en TBD En TBD no existen ramas largas. Para features que no caben en una sola rama, se usan **feature flags**: código completo y testeado que se mergea a master pero desactivado hasta que todas las piezas estén listas. **Feature flag ≠ WIP.** Un flag protege código terminado; un WIP es código a medias. Nunca commitear código incompleto. **Cuándo usar feature flags:** - Feature multi-issue que requiere varias ramas para completarse - Cambio con riesgo que necesita poder desactivarse en producción - Despliegue gradual (activar para un agente primero, después para todos) **Cuándo NO usarlos:** - Issue autocontenido que se completa en una rama → mergear directo - Bug fix, refactor, docs → no necesitan flag **Flujo para features multi-issue:** ``` Feature grande (ej: 0015 Telegram) ├── issue/0015a-telegram-types → pkg/ types, flag OFF → merge ├── issue/0015b-telegram-client → shell/ client, flag OFF → merge ├── issue/0015c-telegram-listener → integration, flag OFF → merge └── issue/0015d-telegram-enable → flag ON, cleanup → merge ``` Cada rama es corta, cada merge es seguro, master nunca se rompe. **Archivo:** `dev/feature_flags.json` ```json { "flags": { "telegram-support": { "enabled": false, "issue": "0015", "description": "Soporte multi-plataforma Telegram", "added": "2026-03-07" } } } ``` ### Comandos disponibles - `/git-branch` — crear rama de trabajo (`.claude/commands/git-branch.md`) - `/git-push` — integrar rama a master y publicar (`.claude/commands/git-push.md`) ## Preferencias del usuario - **Idioma**: español en configs/comentarios de dominio, inglés en código Go - **Estilo**: FP estricto (pure core / impure shell), sin abstracción prematura - **Desarrollo**: trunk-based, Gitea como remote - **Go version**: 1.23.5 en `/usr/local/go/bin` - **No usar** frameworks de agentes externos — arquitectura propia ## Documentacion de desarrollo Ver `dev/README.md` para el indice de documentacion interna (issues pendientes, diseños tecnicos, etc.). Issues detallados en `dev/issues/`. ## Próximas extensiones naturales - Scheduling: cron runner en `shell/` para `ScheduleCfg` - Conversation history: mantener `[]Message` por room en memoria/SQLite - RBAC real: conectar `SecurityCfg.Roles` al listener - E2EE: habilitar `encryption.enabled: true` con crypto store de mautrix - MCP: exponer tools de los agentes como MCP server en el puerto configurado - A2A: agent card HTTP endpoint para comunicación con agentes externos