--- name: dagu-auto description: Genera automatizaciones Dagu (DAGs YAML) - crea workflows, schedules y scripts en ~/dagu/. Usar en vez de cron para cualquier tarea programada. argument-hint: [descripción de la automatización] allowed-tools: Bash, Read, Write, Edit, Glob, Grep --- # dagu-auto Genera una automatización completa en Dagu: DAG YAML + scripts necesarios. **Preferimos Dagu sobre cron para TODA programación de tareas.** ## Sintaxis ``` /dagu-auto backup diario de base de datos /dagu-auto ETL pipeline cada hora /dagu-auto limpiar logs viejos cada domingo /dagu-auto monitorear API cada 5 minutos ``` O Claude puede invocar esta skill cuando detecte que el usuario necesita programar/automatizar algo. ## Precondiciones - [ ] Dagu instalado (`which dagu`) - [ ] Directorio `~/dagu/dags/` existe - [ ] Servicio dagu corriendo (`systemctl --user is-active dagu.service`) Si no se cumplen, instalar y configurar primero: ```bash # Instalar curl -fsSL https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash -s -- --install-dir ~/.local/bin # Crear estructura mkdir -p ~/dagu/{dags,scripts,logs,data} # Configurar servicio mkdir -p ~/.config/systemd/user cat > ~/.config/systemd/user/dagu.service << 'SVCEOF' [Unit] Description=Dagu Workflow Scheduler After=network.target [Service] Type=simple ExecStart=%h/.local/bin/dagu start-all --config=%h/dagu/dagu-config.yaml Restart=on-failure RestartSec=5 [Install] WantedBy=default.target SVCEOF systemctl --user daemon-reload systemctl --user enable --now dagu.service ``` ## Flujo ### 1. Analizar la solicitud Determinar del input ($ARGUMENTS o descripción del usuario): - **Qué automatizar**: la tarea concreta - **Frecuencia**: cron expression (si aplica) - **Dependencias**: pasos secuenciales o paralelos - **Scripts necesarios**: bash, python, go, etc. - **Variables/Parámetros**: configuración dinámica ### 2. Elegir tipo de DAG | Situación | Tipo | |-----------|------| | Pasos secuenciales simples | `type: chain` (default) | | Pasos con dependencias complejas | `type: graph` | | Pasos paralelos | `type: graph` + `max_active_steps` | | Sub-workflows reutilizables | `call:` + archivo separado | ### 3. Generar nombre del DAG ``` # Convención: snake_case, descriptivo, corto backup_postgres_diario etl_ventas_hora limpieza_logs_semanal monitor_api_health ``` ### 4. Crear scripts auxiliares (si necesario) Si el step requiere lógica compleja, crear script en `~/dagu/scripts/`: ```bash # ~/dagu/scripts/nombre_script.sh #!/bin/bash set -euo pipefail # Lógica aquí ``` Siempre dar permisos de ejecución: `chmod +x ~/dagu/scripts/nombre_script.sh` ### 5. Generar el DAG YAML Crear en `~/dagu/dags/nombre.yaml`: ```yaml name: nombre-descriptivo description: Qué hace este workflow tags: [categoria] # Schedule (si aplica) schedule: "expresion_cron" # Variables de entorno env: - VAR_NECESARIA: valor # Parámetros (si necesita configuración) params: - name: PARAM type: string default: valor # Handlers handler_on: failure: command: echo "FALLÓ: ${DAG_NAME}" >> ~/dagu/logs/failures.log steps: - id: paso_1 description: Qué hace este paso command: echo "ejecutando" - id: paso_2 command: bash ~/dagu/scripts/mi_script.sh depends: [paso_1] retry_policy: limit: 3 interval_sec: 10 ``` ### 6. Validar ```bash dagu validate ~/dagu/dags/nombre.yaml ``` Si falla, corregir y re-validar. ### 7. Probar ejecución ```bash dagu start ~/dagu/dags/nombre.yaml # O con parámetros: dagu start ~/dagu/dags/nombre.yaml -- PARAM=valor ``` ### 8. Confirmar resultado Mostrar al usuario: ``` DAG creado: ~/dagu/dags/nombre.yaml Schedule: cada día a las 2:00 AM Steps: 3 pasos (graph mode) Scripts: ~/dagu/scripts/nombre_script.sh Web UI: http://localhost:8090 Validación: OK Test: OK ``` ## Referencia rápida de cron | Expresión | Significado | |-----------|-------------| | `"*/5 * * * *"` | Cada 5 minutos | | `"0 * * * *"` | Cada hora | | `"0 */2 * * *"` | Cada 2 horas | | `"0 9 * * *"` | Cada día a las 9:00 | | `"0 2 * * *"` | Cada día a las 2:00 AM | | `"0 9 * * MON-FRI"` | Lunes a viernes a las 9:00 | | `"0 0 * * SUN"` | Cada domingo a medianoche | | `"0 0 1 * *"` | Primer día de cada mes | | `"CRON_TZ=America/Argentina/Buenos_Aires 0 9 * * *"` | Con timezone | ## Referencia rápida de tipos de step | Tipo | Uso | |------|-----| | `command:` | Comando shell (default) | | `type: http` | Petición HTTP (GET/POST/PUT/DELETE) | | `type: ssh` | Ejecutar en servidor remoto | | `type: jq` | Procesar JSON | | `type: mail` | Enviar email | | `type: chat` | LLM (OpenAI/Anthropic) | | `type: router` | Condicional/branching | | `type: archive` | Comprimir/descomprimir | | `call:` | Sub-workflow | ## Convenciones - Nombres de DAG en snake_case - Siempre incluir `name`, `description`, `tags` - Un handler_on.failure mínimo para logging - Scripts en `~/dagu/scripts/` con `chmod +x` - Validar siempre antes de activar schedule - Usar `type: graph` cuando hay dependencias - Usar `retry_policy` en steps que pueden fallar (HTTP, SSH) - Usar `output:` para pasar datos entre steps ## Errores comunes (Dagu v2.3+) | Error | Causa | Solución | |-------|-------|----------| | `use snake_case keys (dir -> working_dir)` | Usaste `dir:` en un step | Cambiar a `working_dir:` | | `depends field is not allowed for DAGs with type 'chain'` | Usaste `depends:` sin declarar el tipo de DAG | Añadir `type: graph` al nivel raíz del DAG | | `invalid step ID format: must match ^[a-zA-Z][a-zA-Z0-9_]*$` | Guiones medios en step IDs | Usar solo `snake_case` en IDs: `git_push`, no `git-push` | **Regla de oro: SIEMPRE usar `working_dir` (no `dir`), `type: graph` si hay `depends`, y `snake_case` en step IDs.** ## Reglas - SIEMPRE verificar que Dagu está instalado antes de crear DAGs - SIEMPRE validar el DAG después de crearlo - SIEMPRE usar `working_dir` para el directorio de trabajo de un step (NO `dir`) - SIEMPRE usar `type: graph` cuando algún step tiene `depends` - SIEMPRE usar snake_case en step IDs (`mi_paso`, no `mi-paso`) - NUNCA crear crontabs — usar Dagu schedule en su lugar - NUNCA usar rutas relativas en commands — usar rutas absolutas - NUNCA hardcodear secretos — usar `secrets:` o `env:` con referencias - Si el usuario pide "programar algo" o "ejecutar periódicamente", usar Dagu