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

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 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

# 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

# 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.