diff --git a/.claude/rules/create_agent.md b/.claude/rules/create_agent.md index 9fc2d5f..a2864bb 100644 --- a/.claude/rules/create_agent.md +++ b/.claude/rules/create_agent.md @@ -36,7 +36,14 @@ Template base (generado por el scaffold): ```go package // sin guiones: "monitor-bot" → package monitor (strip hyphens, strip _bot) -import "github.com/enmanuel/agents/pkg/decision" +import ( + "github.com/enmanuel/agents/agents" + "github.com/enmanuel/agents/pkg/decision" +) + +func init() { + agents.Register("", Rules) +} func Rules() []decision.Rule { return []decision.Rule{ @@ -56,7 +63,8 @@ func Rules() []decision.Rule { ``` **Reglas estrictas:** -- **PURO**: solo imports de `pkg/decision`, cero I/O, cero side effects +- **PURO**: solo imports de `pkg/decision` y `agents` (para Register), cero I/O, cero side effects +- **Auto-registro**: cada agente se registra via `init()` con `agents.Register("", Rules)` - Package name = ID sin guiones ni `_bot` (e.g. `monitor-bot` → `package monitor`) - **No usar reglas para comandos** (`!help`, `!ping`, etc.) — los comandos se gestionan via `RegisterCommand` (ver policy `create_command.md`) - Las reglas solo aplican a mensajes normales (sin prefijo `!`) @@ -139,18 +147,14 @@ Ejemplo de referencia: `agents/asistente-2/prompts/system.md` El script `new-agent.sh` (ejecutado por `create-full.sh`) hace esto automáticamente. Si falla, hacer manualmente: -**Import** (después de los imports de agentes existentes): +**Blank import** (en la sección de blank imports de agentes): ```go -agent "github.com/enmanuel/agents/agents/" +_ "github.com/enmanuel/agents/agents/" ``` -**rulesRegistry** (dentro del map): -```go -"": agent.Rules, -``` - -El `` es el package name del agent.go (sin guiones, sin `_bot`). -**El ID en rulesRegistry DEBE coincidir exactamente con `agent.id` en config.yaml.** +Las reglas se registran automáticamente via `init()` en el paquete del agente. +No se necesita editar ningún map ni registry manualmente. +**El ID en `agents.Register()` DEBE coincidir exactamente con `agent.id` en config.yaml.** ## Convención de env vars — REGLA CRÍTICA @@ -170,7 +174,7 @@ Checklist a verificar antes de considerar el agente listo: - [ ] `go build -tags goolm ./...` compila sin errores - [ ] `agents//agent.go` exporta `Rules()` y es puro (sin I/O) - [ ] `agents//config.yaml` tiene `agent.id` = nombre del directorio -- [ ] `cmd/launcher/main.go` tiene import + entry en rulesRegistry con el mismo ID +- [ ] `cmd/launcher/main.go` tiene blank import del paquete del agente - [ ] `.env` contiene: `MATRIX_TOKEN_`, `MATRIX_PASSWORD_`, `PICKLE_KEY_`, `SSSS_RECOVERY_KEY_` - [ ] `prompts/system.md` tiene contenido real (no el stub) - [ ] `prompts/system.md` incluye la seccion de seguridad anti-injection (de `.claude/templates/security-prompt.md`) @@ -204,7 +208,7 @@ tail -f run/launcher.log - **Nunca** side effects en `agent.go` - **Siempre** compilar con `-tags goolm` -- **Siempre** que `agent.id` coincida entre config.yaml, rulesRegistry y directorio +- **Siempre** que `agent.id` coincida entre config.yaml, `agents.Register()` y directorio - **No** crear `data/` manualmente — se auto-genera - **No** commitear tokens ni passwords - **No** compartir crypto stores entre agentes diff --git a/dev-scripts/agent/new-agent.sh b/dev-scripts/agent/new-agent.sh index 5f52024..26e76e0 100755 --- a/dev-scripts/agent/new-agent.sh +++ b/dev-scripts/agent/new-agent.sh @@ -310,6 +310,7 @@ YAML cp "$TEMPLATE/agent.go" "$DIR/agent.go" sed -i "s/_template/$PACKAGE/g" "$DIR/agent.go" sed -i "s/Package _template/Package $PACKAGE/g" "$DIR/agent.go" +sed -i "s/AGENT_ID_PLACEHOLDER/$ID/g" "$DIR/agent.go" ok "agent.go creado desde template" # ── Copiar prompts/system.md desde template y personalizar ─────────────── @@ -320,21 +321,21 @@ ok "prompts/system.md creado desde template" ok "Scaffold creado en $DIR/" echo "" -# ── Actualizar cmd/launcher/main.go ─────────────────────────────────────── +# ── Actualizar cmd/launcher/main.go — añadir blank import ──────────────── LAUNCHER="cmd/launcher/main.go" +BLANK_IMPORT="_ \"github.com/enmanuel/agents/agents/$ID\"" -if grep -q "\"$ID\":" "$LAUNCHER" 2>/dev/null; then - warn "$ID ya está en rulesRegistry de $LAUNCHER — saltando" +if grep -q "agents/$ID\"" "$LAUNCHER" 2>/dev/null; then + warn "$ID ya tiene blank import en $LAUNCHER — saltando" else TAB=$'\t' - IMPORT_LINE="${TAB}${PACKAGE}agent \"github.com/enmanuel/agents/agents/$ID\"" - REGISTRY_LINE="${TAB}\"$ID\": ${PACKAGE}agent.Rules," + IMPORT_LINE="${TAB}${BLANK_IMPORT}" - # Insertar import después del último import agents/agents/* + # Insertar blank import después del último blank import de agents/ if awk -v new_import="$IMPORT_LINE" ' { lines[NR] = $0 - if ($0 ~ /[a-z_]+agent "github\.com\/enmanuel\/agents\/agents\/[^"]+"/) + if ($0 ~ /_ "github\.com\/enmanuel\/agents\/agents\//) last_import = NR } END { @@ -346,24 +347,11 @@ else } ' "$LAUNCHER" > /tmp/_launcher_tmp; then mv /tmp/_launcher_tmp "$LAUNCHER" - ok "Import añadido en $LAUNCHER" + ok "Blank import añadido en $LAUNCHER" else - warn "No se pudo insertar el import automáticamente — añádelo manualmente:" + warn "No se pudo insertar el blank import — añádelo manualmente:" echo -e " ${GRN}${IMPORT_LINE}${RST}" fi - - # Insertar entry en rulesRegistry antes del cierre } - if awk -v new_entry="$REGISTRY_LINE" ' - /^var rulesRegistry/ { in_reg = 1 } - in_reg && /^\}/ { print new_entry; in_reg = 0 } - { print } - ' "$LAUNCHER" > /tmp/_launcher_tmp; then - mv /tmp/_launcher_tmp "$LAUNCHER" - ok "Registry entry añadida en $LAUNCHER" - else - warn "No se pudo insertar el registry entry — añádelo manualmente:" - echo -e " ${GRN}${REGISTRY_LINE}${RST}" - fi fi echo ""