Runtime de Hooks (Implementación en Go)
El dominio de hooks en Go proporciona una vía de ejecución rápida, sin dependencias externas y compilada en un único binario para los eventos del ciclo de vida del agente. Reemplaza la implementación original en Node.js para reducir la latencia y la sobrecarga, garantizando la paridad exacta de comportamiento con el entorno de JavaScript.
Flujo principal
Section titled “Flujo principal”El ejecutable único ospec-hooks actúa como un despachador. El nombre del hook a ejecutar se pasa como primer argumento (subcomando).
- El binario lee la carga útil en formato JSON desde la entrada estándar (
stdin). - Delega la ejecución al manejador registrado correspondiente al subcomando.
- El manejador procesa la lógica y devuelve la respuesta escribiendo JSON en la salida estándar (
stdout). - El programa sale con códigos de estado específicos:
0para éxito,1para errores no manejados (codificados como JSON) y2para subcomandos desconocidos.
Detalles técnicos
Section titled “Detalles técnicos”- Registro basado en
init(): Los manejadores se registran automáticamente al inicio de la aplicación, evitando modificaciones en el despachador central. - Manejo de E/S seguro: El paquete
jsoniogarantiza que una entrada vacía se trate como"{}"para evitar fallos de parseo. - Expresiones regulares compatibles con JS: El paquete
rulesutilizaregexp2para soportar aserciones lookahead ((?=...)), las cuales no son compatibles con el motorregexpde la biblioteca estándar de Go, permitiendo la evaluación idéntica de las reglas de seguridad. - Parseo ligero de YAML: El paquete
yamlliteextrae escalares y listas sin depender de un parser YAML completo, manteniendo el binario pequeño.
Decisiones de diseño
Section titled “Decisiones de diseño”- Binario único: Se optó por un único binario compilado cruzado (
ospec-hooks) en lugar de múltiples ejecutables para simplificar el despliegue. - Principio Abierto/Cerrado (OCP): El despachador (
main.goyhandler.go) nunca se modifica al añadir un nuevo hook. Solo se necesita un nuevo archivo que se auto-registre. - Degradación segura: En lugar de hacer panic, los errores se capturan y se devuelven como JSON para que el agente reciba información estructurada y pueda continuar o abortar ordenadamente.
- Paridad estricta: Las validaciones (como en
resultenvelope) usan estructuras ordenadas (slices) para garantizar que los mensajes de error coincidan byte por byte con los de JS (donde iterar unSetpreserva el orden).
Ambas implementaciones son paritarias dentro del mismo runtime de hooks: el binding de eventos, timeouts y responsabilidades de cada hook vive en Runtime de hooks de ciclo de vida, junto al launcher que decide cuándo usar este binario Go o el fallback Node.js.
Puntos de extensión principales
Section titled “Puntos de extensión principales”- Nuevos Hooks: Para añadir un nuevo hook, basta con crear un archivo
<nombre>.goeninternal/hooks/que implemente la interfazHandlery llame ahooks.Register(h)dentro de su funcióninit().
Cosas a vigilar al editar
Section titled “Cosas a vigilar al editar”- No hacer panic: Los manejadores nunca deben hacer panic. Cualquier error debe ser manejado y devuelto como JSON con estado de salida
1. - Reglas Regex: Cualquier nueva regla en
rules.jsondebe seguir siendo compatible conregexp2si utiliza características exclusivas de JS. - Orden determinista: Si se modifican validadores de sobres (
resultenvelope), el orden de los mensajes debe mantenerse idéntico a las definiciones de JS. - Tolerancia de entrada: La entrada
stdinpuede estar vacía o malformada; los paquetes deben procesarla de forma segura.
Mapa de código
Section titled “Mapa de código”/cmd/ospec-hooks/main.go: Punto de entrada, binario único que despacha la ejecución./internal/hooks/handler.go: Interfaz base y registro en memoria (registry) medianteinit()./internal/hooks/*.go: Implementaciones concretas de cada hook (e.g.,sessionstart.go,pretooluse.go)./internal/jsonio/jsonio.go: Utilidades seguras para lectura destdiny escritura destdout./internal/resultenvelope/resultenvelope.go: Espejo en Go del validador de resultados estrictos, garantizando paridad exacta con JS./internal/rules/rules.go: Evaluación de reglas de seguridad (DENY/ASK) usandoregexp2./internal/store/store.go: Puerto en Go de la capa de acceso a almacenamiento de estado del workspace./internal/yamllite/yamllite.go: Parseador ligero para extraer fragmentos YAML sin usar un motor completo.