---
name: agent_scaffold
kind: pipeline
lang: bash
domain: pipelines
version: "1.0.0"
purity: impure
signature: "agent_scaffold(id: string, --display-name string, [--skills cat/skill,...], [--llm provider], [--model model], [--description string], [--tags tags], [--no-register], [--no-commit], [--dry-run]) -> json"
description: "Crea un agente nuevo en agents_and_robots/agents/<id>/ listo para arrancar. Copia el _template/, adapta config.yaml (id, name, version, template:false, llm, skills, matrix env vars), valida skills declaradas, registra el bot en Synapse via bin/register y hace commit en el repo."
tags: [agent, scaffold, matrix, agents_and_robots, launcher]
uses_functions:
  - assert_command_exists_bash_shell
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
  - name: id
    desc: "Identificador del agente en snake-case o kebab-case (ej: monitor-bot, data_analyst). Debe ser unico en agents/."
  - name: display-name
    desc: "Nombre legible que aparece en Matrix y en el system prompt generado (ej: 'Monitor Agent')."
  - name: skills
    desc: "Lista de skills a habilitar, separadas por coma, en formato cat/skill-name (ej: devops/deploy-service,system/health-check). Cada skill debe existir como skills/<cat>/<name>/SKILL.md."
  - name: llm
    desc: "LLM provider: openai (default), anthropic, o claude-code. Determina el proveedor en llm.primary.provider del config.yaml."
  - name: model
    desc: "Modelo LLM especifico (ej: gpt-4o, claude-sonnet-4-20250514). Si se omite, se usa el default del provider."
  - name: description
    desc: "Descripcion corta del agente que se escribe en agent.description del config.yaml y en el stub del system prompt."
  - name: tags
    desc: "Tags separados por coma para agent.tags del config.yaml (ej: monitor,ops,devops)."
  - name: no-register
    desc: "Flag opcional. Si esta presente, omite el paso de registro del usuario bot en Synapse."
  - name: no-commit
    desc: "Flag opcional. Si esta presente, omite el git commit en el repo agents_and_robots."
  - name: dry-run
    desc: "Flag opcional. Muestra el plan completo de ejecucion sin modificar ningún archivo."
output: "JSON con campos: status (ok/error), id, agent_dir (path relativo al registry), skills_enabled (array), registered (bool), committed (bool), message (advertencias si las hay)."
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/pipelines/agent_scaffold.sh"
---

## Ejemplo

```bash
# Crear agente basico con openai
export FN_REGISTRY_ROOT=/home/lucas/fn_registry
bash bash/functions/pipelines/agent_scaffold.sh monitor-bot \
  --display-name "Monitor Agent" \
  --description "Monitorea servicios y reporta estado" \
  --tags "monitor,ops" \
  --llm openai \
  --model gpt-4o

# Crear agente con skills habilitadas y claude-code
bash bash/functions/pipelines/agent_scaffold.sh devops-bot \
  --display-name "DevOps Bot" \
  --skills devops/deploy-service,system/health-check \
  --llm claude-code \
  --description "Bot para operaciones de infraestructura" \
  --no-register --no-commit

# Ver plan sin modificar nada
bash bash/functions/pipelines/agent_scaffold.sh test-bot \
  --display-name "Test Bot" \
  --skills devops/deploy-service \
  --description "Bot de prueba" \
  --no-register --no-commit --dry-run
```

## Salida JSON

```json
{
  "status": "ok",
  "id": "monitor-bot",
  "agent_dir": "projects/element_agents/apps/agents_and_robots/agents/monitor-bot",
  "skills_enabled": ["devops/deploy-service"],
  "registered": true,
  "committed": true
}
```

## Estructura generada

```
agents/<id>/
  config.yaml          # Adaptado desde _template, con id/name/version/template:false
  agent.go             # Copiado del template (reglas puras — editar despues)
  prompts/
    system.md          # Stub minimo si el del template era generico
  knowledge/           # Directorio creado si faltaba
```

## Pasos del pipeline

1. Localizar el proyecto `agents_and_robots` en `projects/element_agents/apps/agents_and_robots/`
2. Validar que el id es valido (snake/kebab-case, sin espacios, no existe ya)
3. Copiar `agents/_template/` a `agents/<id>/`, eliminar `template_para_llm.md` y `PERSONALITIES.md`
4. Editar `config.yaml`: id, name, version, template:false, description, tags, role, llm.provider, llm.model, api_key_env, skills (si aplica), matrix user_id/tokens/crypto paths
5. Validar que cada `cat/skill` declarada en `--skills` existe como `skills/<cat>/<name>/SKILL.md`
6. Crear `prompts/system.md` y `knowledge/` si no existen o son el stub del template
7. Si no `--no-register`: compilar `bin/register` si falta y ejecutar registro en Synapse
8. Si no `--no-commit`: `git add agents/<id>/ && git commit "feat: scaffold agent <id>"`
9. Emitir JSON de resultado

## Variables de entorno requeridas

| Variable | Requerida para | Descripcion |
|---|---|---|
| `FN_REGISTRY_ROOT` | siempre (o ejecutar desde la raiz) | Raiz del fn_registry |
| `MATRIX_ADMIN_TOKEN` | paso 7 (registro) | Token de admin de Synapse |

## Comportamiento de errores

- Si `agents_and_robots/` no existe: error fatal, no crea nada
- Si el id ya existe: error fatal, no sobreescribe
- Si una skill no existe: error fatal con lista de skills disponibles
- Si `bin/register` no compila o falta MATRIX_ADMIN_TOKEN: advertencia en JSON, continua sin registrar
- Si el git commit falla: advertencia en JSON, el agente queda creado en disco

## Notas

El pipeline NO hace push al remote ni arranca el agente. Estos pasos quedan pendientes:
- Editar `agents/<id>/agent.go` para personalizar las reglas de decision (puro)
- Editar `agents/<id>/prompts/system.md` con el system prompt real
- Registrar el blank import en `cmd/launcher/main.go` (ver `.claude/rules/create_agent.md`)
- Reconstruir el launcher: `go build -tags goolm ./...`
- Arrancar: `./dev-scripts/server/restart.sh`
- Push: `/full-git-push` desde el proyecto
