#!/bin/bash # Stop hook: tras cada respuesta del asistente, dispara (en background) la # clasificacion de la fase de la tarea. Lee la ultima respuesta del transcript, # la clasifica con ask_llm (haiku) y escribe el resultado en el goal JSON de la # sesion. El statusline lo pinta en el siguiente render. # # No bloquea el cierre del turno: el trabajo pesado va al worker en background. INPUT=$(cat) SID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null) TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null) [ -z "$SID" ] && exit 0 F="$HOME/.claude/goals/${SID}.json" # Solo si esta terminal tiene un objetivo fijado. [ -f "$F" ] || exit 0 GOAL=$(jq -r '.goal // ""' "$F" 2>/dev/null) [ -z "$GOAL" ] && exit 0 # Salir del estado ACTIVO de inmediato (sincrono, instantaneo): al parar no debe # quedarse mostrando investigando/haciendo/testeando mientras el worker (haiku, # background) afina el reposo a hecho/pendiente_revision/bloqueado/en_pausa. CUR=$(jq -r '.phase // ""' "$F" 2>/dev/null) case "$CUR" in investigando|planificando|haciendo|testeando|puliendo) TMP="${F}.prov.$$" if jq '.phase="en_pausa"' "$F" > "$TMP" 2>/dev/null; then mv "$TMP" "$F"; else rm -f "$TMP"; fi ;; esac [ -z "$TRANSCRIPT" ] && exit 0 [ -f "$TRANSCRIPT" ] || exit 0 # Afinar el reposo en background; el hook retorna de inmediato (no bloquea el # turno). El statusline reflejara el valor final en el siguiente refresco. nohup bash "$HOME/.claude/hooks/goal_phase_worker.sh" "$SID" "$TRANSCRIPT" "$F" >/dev/null 2>&1 & exit 0