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