Efectos

Los efectos de introducción animan las líneas de contenido cuando arranca el fetch. En lugar de imprimir el resultado al instante, cada efecto transforma cada línea desde un estado codificado hasta su texto final durante una corta duración.

Resumen de la Arquitectura

Los efectos son ejecutables independientes con el nombre xfetch-effect-<nombre> (o xfetch-effect-<nombre>.exe en Windows). Reciben las líneas de contenido renderizadas del núcleo de xfetch y devuelven una secuencia de frames.

xfetch core  --->  stdin (JSON request)     --->  effect process
xfetch core  <---  stdout (JSON response)   <---  effect process

Los efectos son opcionales: si el binario del efecto configurado falta o falla, xfetch renderiza la salida normalmente — nada se rompe.

Instalación

# Instalar desde el repositorio oficial de efectos
xfetch effects install decrypt

# Instalar desde un directorio local
xfetch effects install ./my-effect

# Instalar desde un repositorio git personalizado
xfetch effects install my-effect --repo https://github.com/user/effects.git

# Listar efectos instalados
xfetch effects list

# Eliminar un efecto
xfetch effects remove glitch

Los efectos se compilan con cargo build --release y se instalan en ~/.config/xfetch/effects/xfetch-effect-<nombre> (o %APPDATA%\xfetch\effects\ en Windows). El repositorio predeterminado es https://github.com/xfetch-cli/effects.git, que se puede sobrescribir con la variable de entorno XFETCH_EFFECT_REPO.

Configuración

La clave de configuración effects acepta un solo efecto o una lista de efectos que se reproducen en secuencia:

{
    "effects": {
        "plugin": "decrypt",
        "duration_ms": 1500,
        "fps": 30
    }
}

Varios efectos se reproducen uno tras otro:

{
    "effects": [
        {
            "plugin": "glitch",
            "duration_ms": 800,
            "fps": 30
        },
        {
            "plugin": "decrypt",
            "duration_ms": 1500,
            "fps": 30
        }
    ]
}

Campos

CampoTipoDescripción
pluginstringNombre del efecto (instalado como xfetch-effect-<nombre>)
stylestring o nullSugerencia de estilo específica del efecto
duration_msnumber o nullDuración total de la animación en milisegundos
fpsnumber o nullFrames por segundo
argsobject o nullArgumentos libres específicos del efecto
timeout_secsnumber o nullRed de seguridad en segundos: el núcleo termina el proceso del efecto si tarda más

Protocolo JSON wire

Versión del protocolo: 1

Solicitud (stdin)

{
    "version": 1,
    "kind": "effect",
    "lines": [
        "os: Arch Linux x86_64",
        "kernel: 6.6.87.2-arch1-1"
    ],
    "args": {
        "style": null,
        "duration_ms": 1500,
        "fps": 30,
        "args": null
    }
}

El campo lines contiene las líneas de contenido renderizadas (icono + valor por línea) que el efecto transforma. El campo args lleva los parámetros del efecto.

Respuesta (stdout)

{
    "frames": [
        {
            "delay_ms": 33,
            "lines": ["scrambled line 1", "scrambled line 2"]
        },
        {
            "delay_ms": 33,
            "lines": ["os: Arch Linux x86_64", "kernel: 6.6.87.2-arch1-1"]
        }
    ]
}

Cada frame tiene un delay_ms (cuánto tiempo mostrarlo) y lines (el contenido del frame). La respuesta no debe estar vacía, y el último frame debe alcanzar el contenido final original — el núcleo se re-asienta exactamente en el contenido final cuando termina la reproducción.

Manejo de errores

Los efectos deben escribir los errores en stderr y salir con un código de estado distinto de cero. xfetch omite el efecto y renderiza la salida normal si se produce un error.

Efectos Oficiales

EfectoDescripción
decryptRevela cada línea desde glifos codificados hasta su texto real (decodificación suave). Valores por defecto: duration_ms 1500, fps 30.
glitchParpadeo codificado entrecortado con ráfagas de corrupción, franjas horizontales y filas caídas. Valores por defecto: duration_ms 800, fps 30. Mantiene intactas las secuencias de escape ANSI.

Escritura de Efectos Personalizados

Convención de nombres del binario

xfetch-effect-<nombre>          (Linux/macOS)
xfetch-effect-<nombre>.exe     (Windows)

Esqueleto mínimo de un efecto (Rust)

[package]
name = "xfetch-effect-my-effect"
version = "0.1.0"
edition = "2024"

[dependencies]
serde_json = "1"
xfetch-effect-api = { git = "https://github.com/xfetch-cli/api", package = "xfetch-effect-api" }
use xfetch_effect_api::{read_effect_request, write_effect_frames, EffectFrame};

fn main() {
    let request = match read_effect_request() {
        Ok(value) => value,
        Err(err) => {
            eprintln!("{}", err);
            std::process::exit(1);
        }
    };

    let duration_ms = request.args.duration_ms.unwrap_or(1000).max(1);
    let fps = request.args.fps.unwrap_or(30).max(1);
    let frame_count = ((duration_ms * fps) / 1000).max(1);
    let frame_delay = (1000.0 / fps as f64) as u64;

    let mut frames = Vec::with_capacity(frame_count as usize + 1);
    for i in 0..=frame_count {
        let progress = i as f64 / frame_count as f64;
        let lines: Vec<String> = request.lines.iter()
            .map(|line| reveal(line, progress, i))
            .collect();
        frames.push(EffectFrame::new(frame_delay, lines));
    }

    if let Err(err) = write_effect_frames(&frames) {
        eprintln!("{}", err);
        std::process::exit(1);
    }
}

Crate de API para efectos

El crate xfetch-effect-api (código fuente en github.com/xfetch-cli/api) proporciona los tipos y helpers del protocolo:

  • Tipos de protocolo: EffectArgs, EffectFrame, EffectRequest, EffectResponse, KIND_EFFECT
  • Helpers de punto de entrada: read_effect_request(), write_effect_frames()
  • Análisis de argumentos: EffectArgs::parse_args() y EffectArgs::parse_args_or_default()
  • Helpers de timeout: with_timeout() y el error TimedOut

El crate compartido xfetch-effects-lib ofrece helpers seguros para ANSI (SCRAMBLE_GLYPHS, tokenize, reveal, ...) para que los efectos puedan codificar y revelar texto sin romper las secuencias de escape del terminal.

Pautas

  • Mantenga los efectos enfocados en un único estilo visual
  • Escriba los errores en stderr y salga con estado distinto de cero
  • Devuelva un array frames no vacío cuyo último frame coincida con el contenido final
  • Preserve las secuencias de escape ANSI entre frames
  • Maneje los timeouts con elegancia usando with_timeout()