73f7ebb9f5
Mover a completed/ y actualizar estado en README.
7.1 KiB
7.1 KiB
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 consend_messageyllm_prompt(issue 0005)- Las automatizaciones se definen en cada
agents/<id>/config.yamlbajoschedules:, 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ñadirFire(ctx, sc)para testing manualcrons/— datos puros (YAML + Markdown), sin código Godev-scripts/cron/— shell scripts impuros (leen/escriben filesystem, parchean YAML)
Convención de crons/<name>/schedule.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 unREADME.mdque explique la convención - 1.2 Crear
crons/good-morning/schedule.yaml+prompts/message.md(ejemplosend_message) - 1.3 Crear
crons/daily-summary/schedule.yaml+prompts/prompt.md(ejemplollm_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_messageollm_prompt), cron expression - Crea
crons/<name>/schedule.yamly el archivo de prompt/mensaje vacío - Imprime el bloque YAML listo para copiar en
config.yaml
- Pregunta: nombre, descripción, tipo (
- 2.2
dev-scripts/cron/list.sh— lista todas las carpetas bajocrons/con nombre y descripción extraída delschedule.yaml - 2.3
dev-scripts/cron/apply.sh <name> <agent-id>— añade la entradaschedules:aagents/<agent-id>/config.yamlcon los valores por defecto delschedule.yaml. Usayqsi 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)enscheduler.gopara poder disparar un schedule en tests o desde CLI sin esperar al cron - 3.2 Actualizar
scheduler_test.gopara usarFireen lugar de@every 100msdonde sea posible (reduce tiempo de test)
Fase 4: Tests
- 4.1 Test de
Fireparasend_messageinline - 4.2 Test de
Fireparallm_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 deCLAUDE.md - 5.2 Añadir
dev-scripts/cron/en la misma tabla - 5.3 Mención en
dev-scripts/agent/README.mdo creardev-scripts/cron/README.md
Ejemplo de uso
# 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 archivosschedule.yamlson solo documentación + template. No hay un registry Go nuevo; el scheduler sigue leyendo deconfig.yamlcomo hasta ahora. Esto evita añadir un pattern nuevo al proyecto.apply.shopcional: Siyqno 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 100msy 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
yqno disponible en el entorno:apply.shcae back a imprimir el bloque YAML, nunca falla. Sin riesgo real.- Paths relativos en
schedule.yaml: El campotemplateen el YAML es relativo a la raíz del proyecto. Documentar claramente en elREADME.mddel catálogo. - Divergencia entre catálogo y config del agente: Si alguien edita
schedule.yamldespués de aplicarlo, el agente no se actualiza. Es intencional —apply.shes un helper de scaffolding, no sync continua.