intermediate45 minLección 2 de 6

Hooks Personalizados para Automatización

Crea hooks personalizados para automatizar tareas repetitivas en OpenCode. Aprende el ciclo de vida de los hooks, tipos de eventos y cómo crear hooks que validen, transformen y protejan tu flujo de trabajo.

Hooks Personalizados para Automatización

¿Qué Son los Hooks?

Los hooks son scripts que se ejecutan automáticamente en puntos específicos del ciclo de vida de OpenCode. Permiten:

  • Validación — Verificar entradas/salidas antes del procesamiento
  • Transformación — Modificar datos entre pasos
  • Protección — Bloquear operaciones peligrosas
  • Registro — Rastrear actividad para auditoría

Eventos de Hooks

EventoCuándo Se ActivaCaso de Uso
session.startLa sesión comienzaCargar contexto, verificar entorno
session.endLa sesión terminaLimpieza, guardar estado
file.writeAntes de escribir un archivoValidar contenido, formatear código
file.readAntes de leer un archivoControl de acceso, registro
tool.execute.beforeAntes de ejecutar una herramientaVerificaciones de permisos, validación
tool.execute.afterDespués de ejecutar una herramientaPost-procesamiento, registro

Estructura del Hook

.opencode/hooks/my-hook/ ├── hook.json # Hook configuration ├── scripts/ │ └── handler.py # Hook script └── examples/ └── sample-input.json

hook.json

json
{ "name": "validate-frontmatter", "description": "Validates YAML frontmatter in lesson files", "event": "file.write", "pattern": "content/courses/**/*.md", "script": ".opencode/hooks/validate-frontmatter/scripts/handler.py", "blocking": true }
CampoDescripción
nameIdentificador único
descriptionQué hace el hook
eventCuándo activar
patternPatrón de archivos a coincidir (glob)
scriptRuta al script manejador
blockingSi es true, bloquea la operación en caso de fallo

Creando un Hook de Validación

Paso 1: Crear Directorio

bash
mkdir -p .opencode/hooks/validate-frontmatter/scripts

Paso 2: Crear hook.json

json
{ "name": "validate-frontmatter", "description": "Validates YAML frontmatter in Markdown files", "event": "file.write", "pattern": "**/*.md", "script": ".opencode/hooks/validate-frontmatter/scripts/handler.py", "blocking": true }

Paso 3: Crear Script Manejador

python
#!/usr/bin/env python3 """Validate YAML frontmatter in Markdown files. Exit Codes: 0 - Validation passed 1 - Warning (non-blocking) 2 - Validation failed (blocking) """ import os import sys import yaml from pathlib import Path def extract_frontmatter(content: str) -> tuple[str | None, str]: """Extract YAML frontmatter from Markdown content.""" if not content.startswith("---"): return None, content parts = content.split("---", 2) if len(parts) < 3: return None, content return parts[1].strip(), parts[2] def validate_frontmatter(frontmatter: str) -> list[str]: """Validate frontmatter structure and return errors.""" errors = [] try: data = yaml.safe_load(frontmatter) except yaml.YAMLError as e: return [f"Invalid YAML: {e}"] required_fields = ["title", "description", "order"] for field in required_fields: if field not in data: errors.append(f"Missing required field: {field}") if "order" in data: if not isinstance(data["order"], int): errors.append("Field 'order' must be an integer") elif data["order"] < 1: errors.append("Field 'order' must be >= 1") return errors def main() -> int: """Main hook entry point.""" file_path = os.environ.get("OPENCODE_FILE_PATH", "") if not file_path: print("WARNING: OPENCODE_FILE_PATH not set", file=sys.stderr) return 1 path = Path(file_path) if not path.exists(): print(f"ERROR: File not found: {file_path}", file=sys.stderr) return 2 try: content = path.read_text(encoding="utf-8") except Exception as e: print(f"ERROR: Cannot read file: {e}", file=sys.stderr) return 2 frontmatter, _ = extract_frontmatter(content) if frontmatter is None: print(f"WARNING: No frontmatter found in {file_path}") return 1 errors = validate_frontmatter(frontmatter) if errors: for error in errors: print(f"VALIDATION ERROR: {error}", file=sys.stderr) return 2 print(f"VALIDATION PASSED: {file_path}") return 0 if __name__ == "__main__": sys.exit(main())

Paso 4: Hacer el Script Ejecutable

bash
chmod +x .opencode/hooks/validate-frontmatter/scripts/handler.py

Registrando Hooks

Agrega hooks a opencode.json:

json
{ "hooks": { "file.write": [ { "name": "validate-frontmatter", "pattern": "content/courses/**/*.md", "script": ".opencode/hooks/validate-frontmatter/scripts/handler.py", "blocking": true } ], "session.start": [ { "name": "load-context", "script": ".opencode/hooks/load-context/scripts/handler.py", "blocking": false } ] } }

Hooks de Protección

Los hooks de protección bloquean operaciones peligrosas:

python
#!/usr/bin/env python3 """Block writes to protected directories.""" import os import sys from pathlib import Path PROTECTED_PATTERNS = [ ".env", "secrets/**", "*.key", "*.pem", ] def is_protected(path: Path) -> bool: """Check if path matches protected patterns.""" from fnmatch import fnmatch path_str = str(path) for pattern in PROTECTED_PATTERNS: if fnmatch(path_str, pattern): return True if fnmatch(path.name, pattern): return True return False def main() -> int: file_path = os.environ.get("OPENCODE_FILE_PATH", "") if not file_path: return 0 path = Path(file_path) if is_protected(path): print(f"BLOCKED: Cannot write to protected file: {file_path}", file=sys.stderr) return 2 return 0 if __name__ == "__main__": sys.exit(main())

Depuración de Hooks

Habilitar Registro de Depuración

bash
export OPENCODE_DEBUG=1 opencode

Probar Hooks Manualmente

bash
OPENCODE_FILE_PATH=test.md python .opencode/hooks/validate-frontmatter/scripts/handler.py

Verificar Códigos de Salida

CódigoSignificadoAcción
0AprobadoContinuar operación
1AdvertenciaRegistrar, continuar
2BloqueadoDetener operación, mostrar error

Practice Questions

Practice Question

What happens when a blocking hook returns exit code 2?

Practice Question

Which hook event fires before a file is written?

Practice Question

What field in hook.json specifies which files trigger the hook?

Practice Question

How do you test a hook manually?

Practice Question

What is a guard hook used for?


Success

Key Takeaways

  • Los hooks son scripts que se ejecutan automáticamente en puntos específicos del ciclo de vida
  • El evento file.write es ideal para validar contenido antes de guardar
  • Usa código de salida 0 para aprobado, 1 para advertencia, 2 para bloqueado
  • Los hooks de protección safeguard archivos sensibles y operaciones peligrosas
  • Los hooks se registran en opencode.json bajo la clave hooks
  • El campo pattern usa sintaxis glob para coincidir con archivos
  • Prueba los hooks manualmente configurando OPENCODE_FILE_PATH y ejecutando el script
Progreso33%