Files
agents_and_robots/dev/issues/completed/0025-cron-scaffolder.md
T
egutierrez 73f7ebb9f5 chore: cerrar issue 0025-cron-scaffolder
Mover a completed/ y actualizar estado en README.
2026-03-08 20:01:43 +00:00

170 lines
7.1 KiB
Markdown

# 0025 — Catálogo de automatizaciones cron + scaffolder
## Objetivo
Crear un directorio `crons/` como catálogo central de automatizaciones nombradas, y un conjunto de
scripts en `dev-scripts/cron/` para crear nuevas automatizaciones, listarlas y aplicarlas a agentes
sin editar YAML a mano. Evolución directa de la infraestructura creada en el issue 0005.
## Contexto
- `shell/cron/` ya implementa el scheduler con `send_message` y `llm_prompt` (issue 0005)
- Las automatizaciones se definen en cada `agents/<id>/config.yaml` bajo `schedules:`, lo que las
dispersa y dificulta reutilizarlas entre agentes
- No hay forma de crear una nueva automatización sin editar YAML a mano y conocer la estructura
- No existe un catálogo centralizado ni scripts de gestión
- Depende de: issue 0005 (completado)
## Arquitectura
```
crons/ NEW — catálogo de automatizaciones nombradas
good-morning/
schedule.yaml NEW — spec (description, cron, action, output_room por defecto)
prompts/
message.md NEW — plantilla de mensaje
daily-summary/
schedule.yaml NEW
prompts/
prompt.md NEW
dev-scripts/cron/ NEW — herramientas de gestión
new.sh NEW — scaffolder interactivo
list.sh NEW — listar automatizaciones con descripción
apply.sh NEW — añadir automatización a config de agente
shell/cron/scheduler.go MODIFY — añadir Fire(name) para disparo manual en tests
shell/cron/actions.go MODIFY — pequeñas mejoras si surgen al escribir ejemplos
```
### Patrón pure core / impure shell
- `pkg/` — sin cambios (no hay lógica pura nueva)
- `shell/cron/` — modificación mínima: añadir `Fire(ctx, sc)` para testing manual
- `crons/` — datos puros (YAML + Markdown), sin código Go
- `dev-scripts/cron/` — shell scripts impuros (leen/escriben filesystem, parchean YAML)
### Convención de `crons/<name>/schedule.yaml`
```yaml
# Metadata
name: good-morning
description: "Saludo de buenos días en una sala"
# Schedule por defecto (el agente puede sobreescribir)
default_cron: "0 9 * * *"
# Acción
action:
kind: send_message # send_message | llm_prompt
template: prompts/message.md # relativo a la carpeta de la automatización
# Sala por defecto (opcional; el agente puede sobreescribir con output_room)
default_output_room: ""
```
Este archivo es solo **documentación + template**. El agente lo referencia en su `config.yaml`
usando la sección `schedules:` habitual; `apply.sh` automatiza ese paso.
## Tareas
### Fase 1: Estructura `crons/` y automatizaciones de ejemplo
- [ ] **1.1** Crear `crons/` con un `README.md` que explique la convención
- [ ] **1.2** Crear `crons/good-morning/schedule.yaml` + `prompts/message.md` (ejemplo `send_message`)
- [ ] **1.3** Crear `crons/daily-summary/schedule.yaml` + `prompts/prompt.md` (ejemplo `llm_prompt`)
### Fase 2: Scripts de gestión en `dev-scripts/cron/`
- [ ] **2.1** `dev-scripts/cron/new.sh` — scaffolder interactivo:
- Pregunta: nombre, descripción, tipo (`send_message` o `llm_prompt`), cron expression
- Crea `crons/<name>/schedule.yaml` y el archivo de prompt/mensaje vacío
- Imprime el bloque YAML listo para copiar en `config.yaml`
- [ ] **2.2** `dev-scripts/cron/list.sh` — lista todas las carpetas bajo `crons/` con nombre y
descripción extraída del `schedule.yaml`
- [ ] **2.3** `dev-scripts/cron/apply.sh <name> <agent-id>` — añade la entrada `schedules:` a
`agents/<agent-id>/config.yaml` con los valores por defecto del `schedule.yaml`. Usa `yq` si está
disponible; en caso contrario imprime el bloque YAML para copiar a mano
### Fase 3: Mejora menor en `shell/cron/`
- [ ] **3.1** Exportar `Fire(ctx context.Context, sc config.ScheduleCfg)` en `scheduler.go` para
poder disparar un schedule en tests o desde CLI sin esperar al cron
- [ ] **3.2** Actualizar `scheduler_test.go` para usar `Fire` en lugar de `@every 100ms` donde
sea posible (reduce tiempo de test)
### Fase 4: Tests
- [ ] **4.1** Test de `Fire` para `send_message` inline
- [ ] **4.2** Test de `Fire` para `llm_prompt`
- [ ] **4.3** Verificar que `go test -tags goolm ./shell/cron/...` pasa sin regresiones
### Fase 5: Cleanup y docs
- [ ] **5.1** Añadir entrada `crons/` en la tabla de estructura de `CLAUDE.md`
- [ ] **5.2** Añadir `dev-scripts/cron/` en la misma tabla
- [ ] **5.3** Mención en `dev-scripts/agent/README.md` o crear `dev-scripts/cron/README.md`
---
## Ejemplo de uso
```bash
# Crear una nueva automatización
./dev-scripts/cron/new.sh
# → Nombre de la automatización: weekly-report
# → Descripción: Resumen semanal del equipo
# → Tipo de acción [send_message/llm_prompt]: llm_prompt
# → Cron expression [default: 0 9 * * 1]: 0 9 * * 1
# ✓ Creado: crons/weekly-report/schedule.yaml
# ✓ Creado: crons/weekly-report/prompts/prompt.md
#
# Añade esto a agents/<id>/config.yaml:
# schedules:
# - name: weekly-report
# cron: "0 9 * * 1"
# output_room: "!ROOM:server.com"
# action:
# kind: llm_prompt
# template: "crons/weekly-report/prompts/prompt.md"
# Listar automatizaciones disponibles
./dev-scripts/cron/list.sh
# → good-morning send_message "0 9 * * *" Saludo de buenos días
# → daily-summary llm_prompt "0 18 * * *" Resumen diario del equipo
# → weekly-report llm_prompt "0 9 * * 1" Resumen semanal del equipo
# Aplicar a un agente (parchea config.yaml automáticamente)
./dev-scripts/cron/apply.sh good-morning assistant-bot
# → Añadido schedule 'good-morning' a agents/assistant-bot/config.yaml
# → Edita output_room en config.yaml para apuntar a la sala correcta
```
## Decisiones de diseño
- **`crons/` como catálogo de datos, no de código**: Los archivos `schedule.yaml` son solo
documentación + template. No hay un registry Go nuevo; el scheduler sigue leyendo de
`config.yaml` como hasta ahora. Esto evita añadir un pattern nuevo al proyecto.
- **`apply.sh` opcional**: Si `yq` no está disponible, el script imprime el bloque YAML para
copiar a mano. Sin dependencias obligatorias.
- **`Fire()` en lugar de cron real en tests**: Los tests actuales usan `@every 100ms` y duermen
350ms. `Fire()` los hace deterministas e instantáneos.
- **No registry Go para crons**: Añadir un registry compilado (como `cmd/launcher`) para crons
sería over-engineering. La gestión vía shell scripts es suficiente y más flexible.
## Prerequisitos
- Issue 0005 completado (scheduler en `shell/cron/` — ya está)
## Riesgos
- **`yq` no disponible en el entorno**: `apply.sh` cae back a imprimir el bloque YAML, nunca
falla. Sin riesgo real.
- **Paths relativos en `schedule.yaml`**: El campo `template` en el YAML es relativo a la raíz
del proyecto. Documentar claramente en el `README.md` del catálogo.
- **Divergencia entre catálogo y config del agente**: Si alguien edita `schedule.yaml` después
de aplicarlo, el agente no se actualiza. Es intencional — `apply.sh` es un helper de
scaffolding, no sync continua.