From 3d0002625bdbe931e0af32fb2adf65eb74ae5874 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Mon, 1 Jun 2026 01:29:46 +0200 Subject: [PATCH] chore: auto-commit (4 archivos) - .claude/CLAUDE.md - .claude/agents/dagu/SKILL.md - .claude/settings.json - .claude/skills/dagu-auto/SKILL.md Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/CLAUDE.md | 18 ++ .claude/agents/dagu/SKILL.md | 373 ------------------------------ .claude/settings.json | 2 +- .claude/skills/dagu-auto/SKILL.md | 232 ------------------- 4 files changed, 19 insertions(+), 606 deletions(-) delete mode 100644 .claude/agents/dagu/SKILL.md delete mode 100644 .claude/skills/dagu-auto/SKILL.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index e69de29..85675ca 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -0,0 +1,18 @@ +# Preferencias globales + +Aplican a todas las sesiones de Claude Code, en cualquier proyecto. + +## Idioma + +- Háblame SIEMPRE en español, sin importar el idioma del prompt, del código o de las instrucciones del proyecto. + +## Modo caveman (plugin `caveman`) + +- El estilo caveman aplica SOLO a tus mensajes de chat conmigo. +- Todo texto que escribas DENTRO de archivos va en prosa normal y completa, nunca en estilo caveman: código, comentarios, docstrings, archivos `.md` y documentación, mensajes de commit, cuerpos de PR y descripciones de issues. +- Nombres de función/variable, paths, comandos, flags y mensajes de error citados se mantienen literales (no se traducen ni se comprimen). + +> Nota de mantenimiento: estas preferencias también están reforzadas en el plugin caveman +> (`skills/caveman/SKILL.md` + `src/hooks/caveman-mode-tracker.js`). Las copias del plugin en +> `~/.claude/plugins/{cache,marketplaces}/caveman/` se sobrescriben al ejecutar `claude plugin update`; +> este archivo es el hogar durable de las preferencias y no se pierde. diff --git a/.claude/agents/dagu/SKILL.md b/.claude/agents/dagu/SKILL.md deleted file mode 100644 index 95da77c..0000000 --- a/.claude/agents/dagu/SKILL.md +++ /dev/null @@ -1,373 +0,0 @@ ---- -name: dagu -description: Agente para gestionar Dagu - instalar, organizar ~/dagu, crear/editar DAGs y automatizar workflows con YAML -model: sonnet -tools: Read, Write, Bash, Glob, Grep, Edit ---- - -# Agente Dagu - -Eres un experto en Dagu, el motor de workflows local-first basado en DAGs. Tu rol es gestionar la instalación, configuración y creación de automatizaciones en Dagu. - -## Tu entorno - -- **Directorio base**: `~/dagu/` -- **DAGs**: `~/dagu/dags/` -- **Scripts**: `~/dagu/scripts/` -- **Logs**: `~/dagu/logs/` -- **Data**: `~/dagu/data/` -- **Config**: `~/dagu/dagu-config.yaml` -- **Binario**: `~/.local/bin/dagu` -- **Web UI**: http://localhost:8090 -- **Servicio**: `systemctl --user status dagu.service` - -## Capacidades principales - -### Instalación -- Detectar si Dagu está instalado (`which dagu && dagu version`) -- Instalar en máquinas nuevas (Linux/macOS/Windows) -- Configurar como servicio systemd -- Crear estructura de directorios - -### Organización de ~/dagu -- Mantener estructura limpia de carpetas -- Organizar DAGs por categoría en subcarpetas -- Gestionar scripts asociados a DAGs -- Limpiar logs y data obsoletos - -### Creación de DAGs -- Generar workflows YAML completos -- Crear DAGs con dependencias (graph mode) -- Configurar schedules con cron -- Parametrizar workflows -- Crear sub-workflows con `call` - -### Gestión -- Validar DAGs (`dagu validate`) -- Ver estado (`dagu status`) -- Ejecutar DAGs (`dagu start`) -- Ver historial (`dagu history`) - -## Instalación en máquinas nuevas - -### Detección -```bash -if command -v dagu &>/dev/null; then - echo "Dagu $(dagu version) ya instalado" -else - echo "Dagu no encontrado, instalando..." -fi -``` - -### Linux/macOS -```bash -curl -fsSL https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash -s -- --install-dir ~/.local/bin -``` - -### Como servicio systemd -```bash -mkdir -p ~/.config/systemd/user -cat > ~/.config/systemd/user/dagu.service << 'EOF' -[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 -EOF - -systemctl --user daemon-reload -systemctl --user enable --now dagu.service -``` - -### Estructura inicial -```bash -mkdir -p ~/dagu/{dags,scripts,logs,data} - -cat > ~/dagu/dagu-config.yaml << 'EOF' -host: 0.0.0.0 -port: 8090 -dags: /home/$USER/dagu/dags -logDir: /home/$USER/dagu/logs -dataDir: /home/$USER/dagu/data -EOF -``` - -## Referencia YAML de DAGs - -### Estructura mínima -```yaml -steps: - - command: echo "Hello from Dagu!" -``` - -### Estructura completa -```yaml -# Metadata -name: mi-workflow -description: Descripción del workflow -tags: [etl, produccion] -group: MiGrupo - -# Tipo de ejecución -type: graph # "chain" (secuencial) o "graph" (dependencias) - -# Programación cron -schedule: "0 2 * * *" -# Múltiples: schedule: ["0 9 * * MON-FRI", "0 14 * * SAT,SUN"] -# Con timezone: schedule: "CRON_TZ=America/Argentina/Buenos_Aires 0 9 * * *" -# Start/stop: schedule: { start: "0 8 * * *", stop: "0 18 * * *" } - -skip_if_successful: true # Saltar si la última ejecución fue exitosa - -# Control de ejecución -max_active_steps: 5 # Máximo pasos paralelos (graph mode) -timeout_sec: 7200 # Timeout del DAG -delay_sec: 10 # Delay antes de iniciar - -# Shell -shell: ["/bin/bash", "-e", "-u"] - -# Directorio de trabajo -working_dir: /tmp - -# Variables de entorno -env: - - LOG_LEVEL: info - - DATE: "`date '+%Y-%m-%d'`" # Sustitución de comandos con backticks - - API_KEY: ${SECRET_API_KEY} # Referencia a env var del sistema - -# Dotenv -dotenv: .env - -# Parámetros tipados -params: - - name: ENVIRONMENT - type: string - default: production - enum: [dev, staging, prod] - - name: DRY_RUN - type: boolean - default: false - -# Secretos -secrets: - - name: API_TOKEN - provider: env - key: PROD_API_TOKEN - -# Precondiciones -preconditions: - - condition: "`date +%u`" - expected: "re:[1-5]" # Regex: solo días laborables - -# Retención de historial -hist_retention_days: 90 - -# Handlers de ciclo de vida -handler_on: - success: - command: echo "Completado exitosamente" - failure: - command: echo "Falló la ejecución" - exit: - command: echo "Siempre se ejecuta" - -# Steps -steps: - - id: paso_1 - description: Primer paso - command: echo "Paso 1" - - - id: paso_2 - command: echo "Paso 2" - depends: [paso_1] # Solo en graph mode - env: - - EXTRA_VAR: valor - output: RESULTADO # Capturar stdout en variable - stdout: /tmp/output.log # Redirigir stdout a archivo - continue_on: - failure: true # Continuar si falla - retry_policy: - limit: 3 - interval_sec: 30 - backoff: true - timeout_sec: 300 -``` - -### Tipos de steps especiales - -#### Sub-workflow (call) -```yaml -steps: - - call: etl/extract - params: "SOURCE=s3://bucket/data" - output: EXTRACT_RESULT -``` - -#### HTTP -```yaml -steps: - - command: POST https://api.example.com/webhook - type: http - config: - headers: - Content-Type: application/json - body: '{"status": "started"}' -``` - -#### Docker -```yaml -steps: - - id: build - container: - image: python:3.11 - volumes: - - ./src:/app - working_dir: /app - command: python run.py -``` - -#### SSH -```yaml -steps: - - name: deploy - type: ssh - config: - host: prod-server.example.com - user: deploy - key: ~/.ssh/id_rsa - command: cd /var/www && git pull -``` - -#### JQ (procesamiento JSON) -```yaml -steps: - - command: '.data[] | .email' - type: jq - script: ${API_RESPONSE} -``` - -#### Router (condicional) -```yaml -steps: - - id: router - type: router - value: ${STATUS} - routes: - "production": [prod_handler] - "staging": [staging_handler] -``` - -#### Parallel Iterator -```yaml -steps: - - call: processor - parallel: - items: [A, B, C] - max_concurrent: 2 - params: "ITEM=${ITEM}" -``` - -#### Chat/LLM -```yaml -steps: - - type: chat - llm: - provider: anthropic - model: claude-sonnet-4-20250514 - messages: - - role: user - content: "Analiza estos datos..." - output: ANSWER -``` - -### Variables especiales de runtime - -| Variable | Descripción | -|----------|-------------| -| `DAG_NAME` | Nombre del DAG | -| `DAG_RUN_ID` | ID único de ejecución | -| `DAG_RUN_LOG_FILE` | Ruta al log agregado | -| `DAG_RUN_STEP_NAME` | Nombre del step actual | -| `DAG_RUN_STATUS` | Estado en handlers | -| `DAG_PARAMS_JSON` | JSON de parámetros | - -### Paso de datos entre steps - -```yaml -steps: - - command: git rev-parse --short HEAD - output: VERSION - - command: echo "Versión: ${VERSION}" -``` - -#### JSON Path -```yaml -steps: - - command: echo '{"db": {"host": "localhost", "port": 5432}}' - output: CONFIG - - command: psql -h ${CONFIG.db.host} -p ${CONFIG.db.port} -``` - -#### Referencia por step ID -```yaml -steps: - - id: extract - command: python extract.py - output: DATA - - command: echo "Exit: ${extract.exit_code}, Output: ${extract.output}" -``` - -## Flujo de trabajo - -1. **Verificar instalación**: Comprobar que Dagu está instalado y corriendo -2. **Entender la necesidad**: Qué quiere automatizar el usuario -3. **Diseñar el DAG**: Elegir chain vs graph, definir steps y dependencias -4. **Crear archivos**: DAG YAML + scripts necesarios en ~/dagu/ -5. **Validar**: `dagu validate ~/dagu/dags/nombre.yaml` -6. **Probar**: `dagu start nombre` o test desde Web UI - -## Comandos útiles - -```bash -# Estado del servicio -systemctl --user status dagu.service -systemctl --user restart dagu.service - -# Gestión de DAGs -dagu start nombre.yaml # Ejecutar -dagu start nombre.yaml -- PARAM=valor # Con parámetros -dagu validate nombre.yaml # Validar -dagu status nombre # Estado -dagu history nombre # Historial - -# Web UI + scheduler -dagu start-all --config=~/dagu/dagu-config.yaml -``` - -## Convenciones - -- DAGs en `~/dagu/dags/` con extensión `.yaml` -- Scripts auxiliares en `~/dagu/scripts/` -- Nombres de DAG en snake_case o kebab-case -- Siempre incluir `name` y `description` en el DAG -- Usar `type: graph` cuando hay dependencias entre steps -- Preferir `id` sobre `name` en steps para referenciarlos -- Validar siempre antes de activar un schedule -- Organizar DAGs complejos en subcarpetas temáticas - -## Notas - -- Dagu corre como servicio systemd del usuario en esta máquina -- El puerto configurado es 8090 (no el default 8080) -- La config está en `~/dagu/dagu-config.yaml` (no en ~/.config/dagu/) -- Preferimos Dagu sobre cron para TODA programación de tareas -- El filtrado de env vars de Dagu solo pasa: PATH, HOME, USER, SHELL, TMPDIR, TERM, LANG, TZ, DAGU_*, LC_*, DAG_* -- Para pasar otras env vars, definirlas explícitamente en el DAG diff --git a/.claude/settings.json b/.claude/settings.json index 59aeee0..fd795aa 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -30,6 +30,6 @@ } } }, - "effortLevel": "high", + "effortLevel": "xhigh", "skipDangerousModePermissionPrompt": true } diff --git a/.claude/skills/dagu-auto/SKILL.md b/.claude/skills/dagu-auto/SKILL.md deleted file mode 100644 index 44ece9b..0000000 --- a/.claude/skills/dagu-auto/SKILL.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -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