Invita y gana

Cómo funcionan las recompensas

Comparte tu enlace. Cuando un amigo se registre con él y recargue saldo, recibirás la recompensa indicada por sus recargas posteriores.

Stop Hook de Claude Code: verificar antes de «listo»

Configura una comprobación local que bloquee el cierre si fallan pruebas o falta un archivo.

Índice

Stop Hook de Claude Code: verificar antes de «listo»

Que Claude Code diga «listo» solo indica que el agente quiere terminar el turno. No demuestra que se hayan ejecutado las pruebas ni que el artefacto de build sea actual. Un Stop Hook puede hacer una comprobación local breve justo antes de ese cierre y mantener la conversación activa cuando falle una condición concreta. No reemplaza CI, la suite de pruebas completa ni una aprobación manual.

Stop Hook, CLAUDE.md y CI tienen funciones distintas

  • Un Stop Hook ejecuta una comprobación breve al finalizar la respuesta: git diff --check, una prueba enfocada o la presencia de un archivo esperado.
  • CLAUDE.md comunica al agente las reglas y los comandos necesarios, pero el archivo no ejecuta nada por sí mismo.
  • La CI se ejecuta de forma independiente después de un push o una pull request. Sigue siendo la barrera obligatoria para el equipo.

No ponga en este hook un despliegue, una publicación ni escrituras en servicios externos. Al ejecutarse en cada final de turno, esos efectos secundarios son difíciles de repetir y de revertir.

Definir un resultado que se pueda comprobar

Antes de configurar el hook, escriba un contrato de cuatro líneas:

  1. Afirmación: qué puede declarar el agente tras el turno; por ejemplo, «el build está creado».
  2. Prueba: qué comando o archivo lo demuestra, como npm test -- --runInBand y test -s dist/app.js.
  3. Éxito: ambas comprobaciones terminan con el código 0.
  4. Bloqueo de Stop: el hook devuelve JSON con decision: "block" y un reason breve.

Ejecute primero esos comandos sin hook. Si tardan varios minutos o requieren red, sustitúyalos por una comprobación local más acotada; la ejecución completa corresponde a CI.

Si Claude Code usa un proveedor de API, abra primero la guía actual de BetterToken, configure su propia API Key en la herramienta y envíe una solicitud de prueba breve. Después confirme en Dashboard el modelo, el estado y el uso de tokens esperados. El hook local no necesita la clave; no la incluya nunca en sus logs.

Configurar un Stop Hook mínimo

Agregue un hook de proyecto en .claude/settings.json con un límite de tiempo corto:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "./scripts/check-before-stop.sh",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Guarde la comprobación en scripts/check-before-stop.sh. Los comandos del ejemplo son para un proyecto Node: sustitúyalos por comandos y rutas que existan realmente en su repositorio.

#!/usr/bin/env sh
set -eu

if [ -t 0 ]; then
  input='{"stop_hook_active":false}'
else
  input=$(cat)
fi

stop_hook_active=$(printf '%s' "$input" | node -e '
let raw = "";
process.stdin.on("data", chunk => raw += chunk);
process.stdin.on("end", () => {
  try { process.stdout.write(String(Boolean(JSON.parse(raw).stop_hook_active))); }
  catch { process.stdout.write("false"); }
});')

block_stop() {
  if [ "$stop_hook_active" = "true" ]; then
    printf '%s\n' "La comprobación Stop sigue fallando: $block_reason. Ejecútela manualmente; CI sigue siendo obligatoria." >&2
    exit 0
  fi

  BLOCK_REASON="$block_reason" node -e 'process.stdout.write(JSON.stringify({decision:"block",reason:`La comprobación Stop falló: ${process.env.BLOCK_REASON}`}) + "\n")'
  exit 0
}

if ! npm test -- --runInBand >/dev/null 2>&1; then
  block_reason='ejecute npm test y corrija la prueba fallida'
  block_stop
fi

if ! test -s dist/app.js; then
  block_reason='vuelva a generar dist/app.js'
  block_stop
fi

printf '%s\n' 'Comprobación Stop superada: pruebas y dist/app.js'
exit 0

Haga ejecutable el archivo:

chmod +x scripts/check-before-stop.sh

Según la documentación actual de Claude Code, un Stop Hook puede devolver JSON estructurado con código 0: decision: "block" impide terminar el turno y reason comunica la causa. Los códigos distintos de cero y los timeouts tienen su propia semántica de error de hook; no los use como único contrato de bloqueo. La comprobación debe caber dentro del límite configurado.

En el siguiente intento de terminar, stop_hook_active vale true si Claude Code ya continúa por un Stop Hook. La rama fail-open escribe una advertencia breve en stderr y devuelve 0, en vez de volver a bloquear ciegamente el mismo fallo. Así se evita un bucle sin relajar la barrera de CI. Si necesita bloquear otra vez, implemente un contador y un límite propios, sin asumir una cantidad fija no documentada de reintentos.

Verificar el ciclo completo de forma manual

No compruebe solo que el script se inicia en la terminal; pruebe todas las ramas:

  1. En el script, cambie temporalmente dist/app.js por dist/missing.js y ejecute printf '%s\n' '{"stop_hook_active":false}' | ./scripts/check-before-stop.sh; echo $?. Debe ver JSON con "decision":"block", un reason breve y el código 0.
  2. Restaure la ruta correcta, genere el build y repita el comando. El resultado esperado es el código 0.
  3. Vuelva a indicar un archivo inexistente, pida a Claude Code un cambio pequeño y reversible, y confirme que decision: "block" mantiene activa la conversación con la causa de la comprobación.
  4. Sin corregir la ruta, ejecute printf '%s\n' '{"stop_hook_active":true}' | ./scripts/check-before-stop.sh; echo $?. El script debe escribir una advertencia breve en stderr y devolver 0: así habrá validado la rama que evita el bucle.
  5. Restaure la ruta o cree un artefacto actual. En el siguiente final, el hook debe devolver 0 y permitir que el turno termine.

Esta prueba diferencia un Stop Hook operativo de un script que falla en la terminal, pero deja que Claude Code se detenga.

Recuperarse de un Stop bloqueado

Separe dos casos. Si el hook devuelve JSON con decision: "block", lea reason: la condición comprobada falló de forma normal. Ejecute esa comprobación, corrija la prueba o el código, confirme que el archivo procede del comando actual y repita la tarea de Claude Code.

Si el comando del hook termina con código distinto de cero o timeout, es un error de ejecución del hook, no un bloqueo confirmado por reason. Lea el error y stderr, ejecute el script manualmente y corrija la ruta, los permisos, la dependencia o el límite de tiempo antes de volver a probar.

Registre solo el nombre de la comprobación y su resultado. No imprima API Keys, contenido de .env, prompts completos ni logs de prueba íntegros. Un git diff --check correcto no prueba la lógica de negocio; que exista un archivo no prueba que el build sea reciente. El hook solo puede verificar las afirmaciones que usted haya codificado explícitamente.

Mantener separado el workflow de API

Con un proveedor de API, cree y gestione la clave en su propia cuenta. El Stop Hook sigue siendo local: no necesita acceso a la clave, a prompts completos ni a los logs del Dashboard. Si hay un incidente de API, consulte la documentación actual para la Base URL y la configuración; no mezcle ese diagnóstico con la comprobación local de finalización.

Fuentes

¿Quieres optimizar tu flujo de trabajo con LLM?

Conecta modelos mediante una API, gestiona claves y controla el gasto en IA.

Empezar gratis