PostToolUse
Formato automático después de cada edición del agente
PostToolUse
Formato automático después de cada edición del agente
PreToolUse
Bloquear operaciones peligrosas antes de ejecutarlas
Hooks por agente
Hooks específicos que solo activan con un agente concreto
Del ticket al MR
Flujo completo de una feature real con el sistema configurado
El caso de uso más común de hooks. Cada vez que el agente edita un fichero, el hook ejecuta automáticamente el formatter.
Para el equipo:
El código del agente siempre queda formateado sin que el dev lo pida.
Ejemplo — .github/hooks/format-on-edit.json:
{ "event": "PostToolUse", "tools": ["replace_string_in_file", "create_file"], "steps": [ { "run": "npx prettier --write \"${file}\"", "condition": "${file} matches '**/*.ts' or '**/*.html' or '**/*.scss'" }, { "run": "php-cs-fixer fix \"${file}\" --config=.php-cs-fixer.php", "condition": "${file} matches '**/*.php'" } ]}Resultado: cada edición del agente pasa por el formatter del equipo. Sin excepciones.
El hook inspecciona la tool que el agente va a usar antes de ejecutarla. Puede denegarla, modificar su input o pedir confirmación manual.
Ejemplo — .github/hooks/block-dangerous-ops.json:
{ "event": "PreToolUse", "tools": ["run_in_terminal"], "steps": [ { "deny": true, "condition": "${command} matches '*DROP TABLE*' or '${command}' matches '*DROP DATABASE*'", "message": "Operación bloqueada: DROP no permitido desde el agente" }, { "confirm": true, "condition": "${command} matches '*migrate*' or '${command}' matches '*seed*'", "message": "¿Ejecutar migración/seed? Confirmar manualmente." } ]}Casos prácticos:
DROP TABLE en migracionesartisan migrate.env o ficheros de configuración de entornoLos hooks se pueden definir directamente en el frontmatter del .agent.md. Solo se activan cuando ese agente específico está en uso.
Ejemplo: el Reviewer ejecuta PHPStan cada vez que detecta un cambio, sin que ese hook interfiera con el Coder:
---name: Reviewerhooks: PostToolUse: - run: 'vendor/bin/phpstan analyse ${file} --level=5' condition: "${file} matches '**/*.php'" tools: ['read_file']---El hook se ejecuta cuando el dev abre una nueva sesión de chat. Puede inyectar información dinámica que no conviene hardcodear en las instrucciones:
{ "event": "SessionStart", "steps": [ { "run": "echo \"Rama activa: $(git branch --show-current)\"", "inject": true }, { "run": "cat package.json | jq -r '.version'", "inject": true, "label": "Versión del proyecto" } ]}Ideas para el equipo:
El ejercicio central de este bloque. Una feature real recorre el flujo completo:
Ticket → Planner (descompone) → Coder (implementa) → Tests → Reviewer (pre-review) → MRTicket: el dev describe la feature en lenguaje natural al Planner
Planner descompone: tareas técnicas, ficheros afectados, acceptance criteria
Handoff al Coder: implementa Angular Signals + Laravel API siguiendo el plan
Tests automáticos: el Coder genera Karma+Jasmine + PHPUnit
Handoff al Reviewer: pre-review del código generado
MR: el dev revisa el informe del Reviewer, corrige lo necesario y abre el MR
Crear .github/hooks/format-on-edit.json con PostToolUse para Prettier (Angular) y PHP CS Fixer (Laravel)
Crear .github/hooks/block-dangerous-ops.json con PreToolUse — bloqueo de DROP + confirmación de migraciones
Añadir al menos 1 PreToolUse adicional relevante para el proyecto (bloquear edición de .env, impedir rm -rf, bloquear deploy a producción)
Configurar SessionStart para inyectar la rama activa y la versión del proyecto al inicio de cada sesión
Ejecutar el flujo completo Planner → Coder → Reviewer con una feature del sprint (diferente a la de la sesión)
Medir tiempo: anotar cuánto tardaste con el agente vs estimación sin él — traer el dato a la sesión 5