Todos los productos
Search
Centro de documentos

Qoder CN Series:Hooks

Última actualización: Sep 23, 2026

Los hooks inyectan lógica personalizada en puntos clave del ciclo de vida del agente de Qoder CN. Mediante un archivo de configuración JSON, usted puede:

  • Bloquear operaciones peligrosas antes de llamar a una herramienta.

  • Ejecutar un linter después de cada escritura de archivo para aplicar el estilo de código.

  • Recibir una notificación de escritorio cuando el agente termina una tarea.

A diferencia de las instrucciones del prompt, los hooks son deterministas. Cuando ocurre un evento registrado, el script se ejecuta sin importar la interpretación del modelo.

Eventos compatibles

Qoder CN es compatible con cinco eventos de hook:

Nombre del evento

Activador

Bloqueable

UserPromptSubmit

Después de que el usuario envía un prompt, pero antes de que el agente lo procese.

Sí

PreToolUse

Antes de ejecutar una llamada a una herramienta.

Sí

PostToolUse

Después de que una llamada a una herramienta se completa correctamente.

No

PostToolUseFailure

Después de que falla una llamada a una herramienta.

No

Stop

Cuando el agente termina su respuesta.

No

Inicio rápido

Este ejemplo configura un hook que bloquea rm -rf.

Paso 1: Cree el script

mkdir -p ~/.lingma/hooks
cat > ~/.lingma/hooks/block-rm.sh << 'EOF'
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')

if echo "$command" | grep -q 'rm -rf'; then
  echo "Dangerous command blocked: $command" >&2
  exit 2
fi

exit 0
EOF
chmod +x ~/.lingma/hooks/block-rm.sh

Paso 2: Agregue la configuración

Agregue a continuación el contenido en ~/.lingma/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.lingma/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}

Paso 3: Compruebe el resultado

Reinicie el IDE. En el panel de Qoder CN, pida al agente que ejecute un comando que contenga rm -rf. El hook bloquea la ejecución y devuelve el mensaje de error al agente.

Casos de uso

Escenario

Evento

Descripción

Bloquear comandos peligrosos

PreToolUse

Bloquee comandos como rm -rf o DROP TABLE.

Validar rutas de archivos

PreToolUse

Restrinja la escritura de archivos a directorios designados.

Lint o formato automático

PostToolUse

Ejecute ESLint o Prettier automáticamente después de escribir archivos.

Registro de auditoría

PostToolUse

Registre todas las llamadas a herramientas del agente para auditorías de seguridad.

Supervisión de errores

PostToolUseFailure

Envíe alertas o registre errores cuando falle una llamada a una herramienta.

Filtrar contenido de prompts

UserPromptSubmit

Analice los prompts en busca de datos confidenciales, como contraseñas o claves.

Inyección automática de contexto

UserPromptSubmit

Agregue directrices del proyecto o convenciones de código a los prompts.

Notificaciones de escritorio

Stop

Envíe una notificación de escritorio cuando el agente termine.

Cómo funciona

Los hooks requieren dos pasos: escribir un script y registrarlo en el archivo de configuración.

Cuando el agente alcanza un evento del ciclo de vida, la extensión busca los hooks correspondientes:

  1. El IDE carga todas las configuraciones de hooks al iniciar.

  2. El agente alcanza un nodo de evento (por ejemplo, PreToolUse).

  3. La extensión recorre los grupos de hooks y los compara con el contexto actual.

  4. Los scripts coincidentes se ejecutan en el orden declarado.

  5. El script recibe el contexto del evento (JSON) mediante stdin y devuelve una decisión a través del código de salida y stdout.

  6. El IDE usa el resultado para permitir o bloquear la operación.

Requisitos previos

  • jq: se usa para analizar sintácticamente JSON en los ejemplos. Instálelo con brew install jq (macOS) o apt install jq (Linux).

  • Permisos del script: los scripts de hook deben tener permisos de ejecución (chmod +x).

Creación de hooks

Paso 1: Defina el requisito

Determine cuándo intervenir y qué debe coincidir:

I want to intercept/handle "what operation" "when"?
                              ↓             ↓
                           Write matcher   Choose event

Requisito

Evento

Matcher

Inspeccionar comandos de shell antes de ejecutarlos.

PreToolUse

"Bash"

Procesar archivos después de escribirlos o editarlos.

PostToolUse

`"Write

Edit"`

Registrar cuando falla una llamada a una herramienta del agente.

PostToolUseFailure

"Bash" u omitir

Filtrar todos los prompts del usuario.

UserPromptSubmit

Omitir (coincide con todo)

Activar una notificación cuando el agente se detiene.

Stop

Omitir (coincide con todo)

Interceptar solo herramientas MCP.

PreToolUse

"mcp__.*"

Paso 2: Escriba el script del hook

Los scripts de hook siguen este protocolo:

  • Entrada: recibe el contexto del evento como un objeto JSON mediante stdin.

  • Salida: controla el comportamiento mediante su exit code.

exit 0   →  Allow (proceed with execution)
exit 2   →  Block (stop the operation; stderr is fed back to the Agent)
Other    →  Error (proceed with execution; stderr is displayed to the user)

Plantilla de script:

#!/bin/bash

# 1. Read JSON input from stdin.
input=$(cat)

# 2. Extract the fields you need with jq.
#    Different events have different fields; see the "Event Reference" section for details.
tool_name=$(echo "$input" | jq -r '.tool_name')
tool_input=$(echo "$input" | jq -r '.tool_input')

# 3. Write your validation logic.
if [ "$tool_name" = "Bash" ]; then
  command=$(echo "$input" | jq -r '.tool_input.command')

  # Check for dangerous operations.
  if echo "$command" | grep -qE 'rm\s+-rf|DROP\s+TABLE'; then
    # Block: exit 2 + stderr message is fed back to the Agent.
    echo "Operation denied: $command" >&2
    exit 2
  fi
fi

# 4. Allow the operation.
exit 0

También puede generar JSON con exit 0 para obtener un control más preciso:

#!/bin/bash
input=$(cat)

# Output JSON for fine-grained control (only takes effect on exit 0).
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"This operation is not allowed"}}'
exit 0

Paso 3: Registre el script en el archivo de configuración

Registre el script bajo el evento correspondiente:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "MatchCondition (optional)",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/your/script.sh"
          }
        ]
      }
    ]
  }
}

Paso 4: Pruebe y depure

Pruebe los hooks si canaliza la entrada JSON desde la terminal:

# Simulate a PreToolUse event
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"},"hook_event_name":"PreToolUse"}' \
  | ~/.lingma/hooks/block-rm.sh
echo "Exit code: $?"

Revise la salida de stderr (mensaje de bloqueo):

echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' \
  | ~/.lingma/hooks/block-rm.sh 2>&1

Configuración de hooks

Ubicaciones de los archivos de configuración

Los hooks se combinan a partir de estos archivos, de menor a mayor prioridad:

Ubicación

Alcance

Prioridad

Compartible

Descripción

~/.lingma/settings.json

Usuario

1 (la más baja)

No

Se aplica a todos los proyectos.

.lingma/settings.json

Proyecto

2

Sí

Se puede confirmar en git para compartirlo con el equipo.

.lingma/settings.local.json

Proyecto (local)

3 (la más alta)

No

Anulaciones personales. Agréguelo a .gitignore.

Nota

No se admite la recarga en caliente. Reinicie el IDE para que los cambios de configuración surtan efecto.

Formato de configuración

{
  "hooks": {
    "EventName": [
      {
        "matcher": "MatchCondition",
        "hooks": [
          {
            "type": "command",
            "command": "command_to_run"
          }
        ]
      }
    ]
  }
}

Campo

Obligatorio

Descripción

type

Sí

Debe establecerse en "command".

command

Sí

El comando de shell o la ruta del script que se va a ejecutar.

timeout

No

Tiempo de espera en segundos. Valor predeterminado: 30.

matcher

No

Filtra cuándo se ejecuta el hook. Si se omite, se activa en todas las invocaciones del evento.

Un solo evento puede tener varios grupos de matchers, cada uno con varios comandos de hook.

Reglas de coincidencia del matcher

Un matcher restringe cuándo se activa un hook. Los campos evaluados varían según el evento.

Sintaxis

Significado

Ejemplo

Omitir o "*"

Coincidir con todo

Se activa para todas las herramientas.

Valor exacto

Coincidencia exacta

"Bash" se activa solo para la herramienta Bash.

Separado por `

`

Coincidir con varios valores

`"Write

Edit"` se activa para las herramientas Write o Edit.

Expresión regular

Coincidencia de expresión regular

"mcp__.*" coincide con todas las herramientas MCP.

Asignación de nombres de herramientas

Qoder CN asigna dos conjuntos de nombres de herramientas en tiempo de ejecución: nativos y compatibles. Por ejemplo, matcher: "Bash" y matcher: "run_in_terminal" son equivalentes.

Nombre nativo

Nombre compatible

Descripción

run_in_terminal

Bash

Ejecuta un comando de shell.

read_file

Read

Lee el contenido de un archivo.

create_file

Write

Crea un archivo o escribe en él.

search_replace

Edit

Edita un archivo.

delete_file

-

Elimina un archivo.

grep_code

Grep

Busca contenido en archivos.

search_file

Glob

Coincide con nombres de archivos.

list_dir

LS

Enumera el contenido de un directorio.

task

Task

Inicia una subtarea o un subagente.

mcp__<server>__<tool>

Igual que el nativo

Una herramienta MCP.

Escritura de scripts de hook

Los scripts de hook reciben JSON mediante stdin e indican decisiones a través de exit code y stdout. Los campos específicos de cada evento se describen en la sección Referencia de eventos.

Entrada

Todos los eventos comparten estos campos de stdin:

Campo

Descripción

session_id

El identificador de la sesión actual.

cwd

El directorio de trabajo actual.

hook_event_name

El nombre del evento activado.

transcript_path

La ruta del archivo al JSON del contexto de la sesión.

Los eventos agregan campos adicionales a esta base (enumerados en la Referencia de eventos). Analícelos con jq:

#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')

Salida

Un script indica su decisión mediante su exit code y los datos escritos en stdout.

El código de salida determina el comportamiento básico:

Código de salida

Significado

Comportamiento

0

Correcto

Continúa la ejecución y analiza sintácticamente el JSON de stdout.

2

Bloqueo

Bloquea la operación y envía stderr al agente (solo en eventos bloqueables).

Otro

Error

Continúa la ejecución y muestra stderr al usuario.

JSON de stdout (opcional; solo surte efecto cuando el código de salida es 0):

{
  "continue": true,
  "stopReason": "",
  "suppressOutput": false,
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow | deny | ask",
    "permissionDecisionReason": "Reason for the decision"
  }
}

Referencia de eventos

UserPromptSubmit

  • Activador: después de que el usuario envía un prompt, pero antes de que el agente lo procese.

  • Bloqueable: sí (el código de salida 2 cancela la solicitud).

  • Campos de entrada adicionales: prompt (el texto sin procesar que ingresó el usuario).

PreToolUse

  • Activador: antes de que el agente ejecute una llamada a una herramienta.

  • Bloqueable: sí (el código de salida 2 rechaza la llamada a la herramienta).

  • Campo del matcher: tool_name.

  • Campos de entrada adicionales: tool_name, tool_input.

PostToolUse

  • Activador: después de que una llamada a una herramienta se completa correctamente.

  • Bloqueable: no.

  • Campo del matcher: tool_name.

  • Campos de entrada adicionales: tool_name, tool_input, tool_response.

PostToolUseFailure

  • Activador: después de que falla una llamada a una herramienta.

  • Bloqueable: no.

  • Campo del matcher: tool_name.

  • Campos de entrada adicionales: tool_name, tool_input, error.

Stop

  • Activador: cuando el agente termina su respuesta.

  • Bloqueable: no.

  • Campos de entrada adicionales: stop_hook_active, last_assistant_message.

Preguntas frecuentes

¿Por qué los cambios de configuración no surten efecto?

No se admite la recarga en caliente. Reinicie el IDE después de modificar settings.json.

¿Qué sucede si un script de hook supera el tiempo de espera?

Un tiempo de espera agotado (valor predeterminado: 30 s) se trata como un error. La ejecución continúa y se muestra stderr al usuario.

¿Cómo se determina el orden de ejecución de varios hooks?

Los hooks del mismo evento se ejecutan en el orden declarado. Entre archivos se aplica la siguiente prioridad: usuario (la más baja) → proyecto → proyecto local (la más alta).

¿A qué variables de entorno pueden acceder los scripts de hook?

Los hooks se ejecutan en la raíz del proyecto con el usuario actual y heredan el entorno del proceso del IDE.

¿Cómo consulto los registros de ejecución de los hooks?

La salida de stderr se envía al agente o al usuario. Para consultar registros detallados, busque el prefijo [hook] en los registros de ejecución de Qoder CN.