Instalación y primer inicio

Por: Artiko
buzznostrinstalacionescritoriorelaylinux

Instalación y primer inicio

En el capítulo anterior viste qué es Buzz. Ahora toca lo concreto: bajar la aplicación, conectarla a un relay y dejar tu primer mensaje.

Hacen falta dos cosas, y conviene tenerlas separadas en la cabeza. El cliente: la app de escritorio, construida con Tauri y React, que instalas en tu máquina. Y el relay: el servidor que hospeda la comunidad, cuya URL es la comunidad. Sin relay, el cliente no tiene a dónde conectarse.

Los clientes móviles para iOS y Android aparecen en el README de Buzz en la columna 🚧 Being wired up, no en la de lo que funciona hoy: la puerta de entrada sigue siendo el escritorio. En Otros clientes: Nostr de terceros y móvil verás qué se puede hacer mientras tanto con clientes Nostr genéricos.


Descargar la app empaquetada

Las builds se publican en la página de releases del repositorio block/buzz. Cada release de escritorio adjunta un artefacto por plataforma, y el nombre del archivo lleva la versión en el medio.

PlataformaArchivo
macOS, Apple SiliconBuzz_<version>_aarch64.dmg
macOS, IntelBuzz_<version>_x64.dmg
Linux x86_64Buzz_<version>_amd64.AppImage o Buzz_<version>_amd64.deb
Windows x64Buzz_<version>_x64-setup_alpha-unsigned.exe

Tres detalles conviene fijarlos:

  • No hay un DMG universal. El pipeline construye dos DMG de macOS por separado, darwin-aarch64 y darwin-x86_64; ambos van firmados, notarizados y colgando del mismo release.
  • Linux tiene dos formatos para la misma arquitectura: AppImage portable y paquete .deb. No son intercambiables en cuanto a compatibilidad, como verás en la sección de problemas de render.
  • El instalador de Windows lleva alpha-unsigned en el nombre a propósito. El marcador no es decorativo: describe exactamente lo que es.

Cómo saber si tu Mac es Apple Silicon o Intel

Es la duda más común y se resuelve en dos clics, sin terminal:

  1. Abre el menú Apple en la esquina superior izquierda.
  2. Elige About This Mac o Acerca de este Mac.

Y luego lee la línea del procesador:

  • Si dice “Chip: Apple …” (por ejemplo Apple M2), es Apple Silicon: baja el aarch64.dmg.
  • Si dice “Processor: Intel …”, es Intel: baja el x64.dmg.
flowchart TD
    A["Menú Apple → About This Mac"] --> B{"¿Qué línea aparece?"}
    B -->|"Chip: Apple ..."| C["Apple Silicon → Buzz_version_aarch64.dmg"]
    B -->|"Processor: Intel ..."| D["Intel → Buzz_version_x64.dmg"]

Windows: el aviso de SmartScreen

La build de Windows no está firmada con un certificado de código. Por eso SmartScreen puede interponerse en el primer lanzamiento con la pantalla azul que dice “Windows protected your PC”.

Para continuar: pulsa More infoMás información— y luego Run anywayEjecutar de todas formas—. Si el botón More info no aparece, el diálogo se está mostrando en su versión reducida; descarga el archivo de nuevo desde la página oficial de releases. Nunca saltes esta pantalla para un binario cuyo origen no puedas rastrear hasta el release del repositorio.

Si trabajas en Block

Hay un camino distinto: ni construir desde el código fuente ni usar el release open source, sino la build interna de squareup/buzz-releases, que viene precableada al relay y al proveedor de agentes internos. Si ese es tu caso, salta la sección de conexión al relay: ya viene resuelta.


Prerrequisito de Windows: Git for Windows

Esto no es opcional si vas a trabajar con agentes, y es el tropiezo número uno en Windows.

La herramienta de shell que usan los agentes ejecuta los comandos bajo bash. En macOS y Linux bash ya está en el sistema. En Windows no, así que hay que traerlo: se instala Git for Windows, que incluye Git Bash, y eso es lo que Buzz resuelve en tiempo de ejecución. Una vez instalado, todo funciona igual que en las otras plataformas.

Al instalar, elige la opción “Git from the command line and also from 3rd-party software”. El resolvedor de Buzz sabe llegar a Git Bash desde ahí: esa opción pone Git\cmd\git.exe en el PATH, y desde ese git.exe Buzz deriva su hermano estable Git\bin\bash.exe.

El orden real en que Buzz busca el shell en Windows

El resolvedor prueba, en este orden, y el primero que acierta gana:

  1. La variable de entorno BUZZ_SHELL.
  2. La variable de entorno GIT_BASH, mantenida por compatibilidad.
  3. bash.exe en el PATH, excluyendo System32 para no resolver por error el lanzador de WSL.
  4. git.exe en el PATH, y desde ahí su hermano ..\bin\bash.exe.
  5. Las rutas estándar bajo ProgramFiles, ProgramFiles(x86) y LocalAppData.
  6. El InstallPath de Git for Windows en el registro, de máquina y de usuario.

Si ninguna acierta, el error nombra exactamente todo lo que se intentó y te pide instalar Git for Windows desde git-scm.com/download/win con esa opción de PATH.

La variable BUZZ_SHELL

Si prefieres apuntar Buzz a otro shell compatible con bash, define BUZZ_SHELL con su ruta:

BUZZ_SHELL=C:\path\to\bash.exe

Tres cosas que el código deja claras sobre esta variable:

  • La descripción de la herramienta que ve el agente se actualiza sola: su bootstrap incluye una línea del estilo Shell: <nombre> (set BUZZ_SHELL to override) — write command strings in that shell's syntax, así que el agente sabe en qué dialecto escribir sus comandos.
  • El flag de invocación se ajusta al shell: -c para bash, zsh y sh; /C para cmd; -Command para powershell y pwsh.
  • También se respeta en macOS y Linux, para optar por zsh u otro shell. Si apunta a una ruta que no existe, el resolvedor no falla: cae de vuelta a bash.

Cuando BUZZ_SHELL es un nombre desnudo y no una ruta, se busca recorriendo el PATH del proceso; en Windows esa búsqueda no aplica la exclusión de System32, porque si pediste cmd o powershell tiene sentido hallarlos donde viven.


Conectarse al relay

Aquí es donde la instalación deja de ser genérica y se vuelve tuya.

Por defecto, la app se conecta a ws://localhost:3000: el valor que usa la build open source cuando no le dices nada, pensado para quien levantó un relay en su propia máquina.

La precedencia exacta

El escritorio resuelve la URL del relay así, y el primero que exista gana:

flowchart TD
    A["Override de workspace elegido dentro de la app"] --> B["Variable de entorno BUZZ_RELAY_URL"]
    B --> C["Valor fijado al compilar la build"]
    C --> D["Default ws://localhost:3000"]
    A -.->|"gana si está presente"| E["URL efectiva del relay"]
    B -.-> E
    C -.-> E
    D -.-> E

Traducido a decisiones prácticas: el override elegido dentro de la app manda sobre todo lo demás, así que si añadiste una comunidad desde la interfaz, esa selección pesa más que cualquier variable de entorno. BUZZ_RELAY_URL se lee del entorno del proceso, se recorta de espacios y se ignora si queda vacía. Existe una variable hermana, BUZZ_RELAY_HTTP, para la base HTTP de la API; si no la defines, esa base se deriva de la URL de WebSocket: wss:// pasa a https:// y ws:// pasa a http://, quitando la barra final.

Apuntar a otro relay con la variable de entorno

Antes de lanzar la app:

# macOS / Linux
BUZZ_RELAY_URL=wss://relay.example.com /Applications/Buzz.app/Contents/MacOS/buzz-desktop
# Windows, PowerShell
$env:BUZZ_RELAY_URL = "wss://relay.example.com"

Si lanzas la app con doble clic, la variable tiene que estar definida en el entorno que hereda esa app, no en una terminal aparte. Para el uso diario es más cómodo cambiar el relay desde dentro de la aplicación.

Cambiar el relay desde la propia app

La interfaz tiene un diálogo de Add community con dos caminos:

  • “Create a new community”, Claim a Buzz address for your team. Abre Builderlab en el navegador. Es un flujo de operador, cubierto en el curso de administrador.
  • “Join an existing community”, Use a community URL or invite link. Este es tu camino como usuario.

En el formulario de unirse, el campo se llama “Community URL or invite link” y el marcador de posición es https://community.example.com or paste an invite link. Si lo que pegaste es un código de invitación desnudo, aparece un segundo campo “Relay URL” con marcador wss://relay.example.com.

Lo que escribes se normaliza antes de guardarse:

Lo que escribesLo que queda guardado
wss://relay.example.comigual, validado como URL
ws://localhost:3000igual, validado como URL
https://relay.example.comwss://relay.example.com
http://localhost:3000ws://localhost:3000
relay.example.com sin esquemawss://relay.example.com

Las barras finales se recortan siempre, y un valor con espacios o malformado se rechaza en vez de guardarse a ciegas. Después de normalizar, la app sondea el relay: abre una conexión WebSocket con un límite de 4 segundos y la cierra enseguida. Si el socket abre, la URL sirve. Si no, verás el aviso “Can’t reach this relay — check the URL”, con la opción de continuar de todas formas por si el relay está momentáneamente caído pero la URL es correcta.

Y si todavía no tienes un relay

Sin relay no hay comunidad, y la app se queda mirando ws://localhost:3000 sin nadie al otro lado. Tres salidas razonables, en orden de esfuerzo:

  1. Pídesela a tu equipo. El caso normal: alguien ya levantó el relay y solo necesitas la URL de la comunidad o un enlace de invitación. Pégalo en Join an existing community y listo.
  2. Despliega uno en Railway. El README incluye un botón de Deploy on Railway que levanta un relay para tu equipo sin administrar servidores, y remite al artículo de ingeniería de Block sobre correr tu propio relay.
  3. Levántalo tú. Requiere Docker y Hermit, y pasa por just setup, just build y just dev, que arranca relay y escritorio juntos en ws://localhost:3000. Esto ya es territorio de operador: relay, membresía, almacenamiento y seguridad se cubren en el curso de administrador.

Primer arranque

Con la app instalada y el relay a la vista, el primer lanzamiento hace tres cosas en cadena.

sequenceDiagram
    participant U as Tú
    participant A as App de escritorio
    participant K as Almacén de claves del sistema
    participant R as Relay de la comunidad
    U->>A: Abres Buzz por primera vez
    A->>K: Resuelve o crea el par de claves
    K-->>A: Identidad activa más su ubicación
    A->>R: Se conecta y autentica firmando el reto
    A->>U: Paso 1, nombre visible
    A->>U: Paso 2, avatar
    A->>R: Publica tu perfil en esta comunidad
    R-->>A: Canales iniciales disponibles
    U->>R: Primer mensaje firmado con tu clave

1. Se crea tu identidad

Buzz no tiene registro, ni contraseña, ni correo de verificación. Tu par de claves es tu identidad. En el primer arranque la app resuelve una identidad y registra dónde quedó guardada; los cuatro estados posibles de esa ubicación son ephemeral, system-keyring, local-file y environment, y lo esperable en un escritorio normal es el llavero del sistema. Si ya tienes una clave Nostr, el flujo ofrece importarla en vez de generar otra.

Todo lo que rodea a esa clave —npub y nsec, respaldo, pérdida, segundo dispositivo— es el tema de Tu identidad: claves, perfil y dispositivos. Aquí basta con saber que el respaldo cifrado es recomendado, no obligatorio: el botón de continuar del paso de backup nunca está deshabilitado, así que puedes posponerlo. Pospónlo poco.

2. Completas el perfil de la comunidad

El onboarding acotado a la comunidad tiene exactamente dos pasos:

  1. Perfil, con el encabezado literal “What should we call you?”. Aquí eliges tu nombre visible. Este mismo paso es donde puedes desviarte a importar una clave existente.
  2. Avatar, que se puede saltar.

Recuerda la regla de portabilidad de Buzz: la clave viaja contigo a todas las comunidades, pero el perfil es por comunidad. Cuando te unas a otra, vuelves a publicar tu perfil ahí. Y si el relay exige membresía y tu clave no está en el padrón, el flujo no te deja pasar: eso no se arregla desde el cliente, tiene que añadirte alguien con permisos de operador (curso de administrador).

3. Aterrizas en los canales iniciales

Una comunidad recién creada trae canales de arranque, de tipo stream y visibilidad open: generalGeneral conversation and community updates— y welcome-everyoneSay hi, ask a question, or share what brought you here—. Puede aparecer además un canal privado llamado Welcome, A private channel for getting oriented in this community, pensado para orientarte sin ruido.

4. Tu primer mensaje

Abre #welcome-everyone, haz clic en el compositor —cuyo marcador de posición es literalmente Message #welcome-everyone— escribe y envía.

Lo que pasó por debajo: tu cliente construyó un evento firmado con tu clave privada, lo mandó al relay por WebSocket y el relay lo aceptó porque eres miembro de ese canal. La membresía de canal es la única puerta, y se verifica en cada operación. Ese mensaje ya es buscable, auditable y visible para cualquier agente miembro del canal. La mecánica completa de mensajes, ediciones, adjuntos y menciones está en Canales y mensajes.

La tarjeta de conexión del relay

En la barra lateral hay una tarjeta que informa del estado de la conexión, y sus textos te dicen exactamente qué está pasando:

EstadoQué vesQué significa
ConectadoConnectedLa sesión con el relay está viva
ReconectandoConnecting / ReconnectingEl cliente está reintentando solo
Esperando ayudaWaiting to reconnectHay un asistente de reconexión con diálogos abiertos que debes completar
Sin conexiónCan’t reach the relay / Click to connectLa URL no responde

Si te quedas clavado en el último estado, revisa en orden: URL correcta, relay arriba, clave admitida en la comunidad.


Problemas de render en Linux

Linux es la plataforma donde la app puede arrancar y no pintar nada: el proceso vivo, la ventana en blanco o transparente y ningún mensaje de error. No es esotérico, es WebKitGTK peleándose con el driver gráfico. El repositorio tiene una guía dedicada, y esto es lo que dice.

Tabla de síntoma a solución

SíntomaCausa probableSolución
Ventana en blanco o transparente y luego SIGABRT con colrv1_configure_skpaint en la salidaFuente de emoji a color en formato COLRv1, solo AppImageActualiza al AppImage más reciente, v0.5.2 o superior
Ventana en blanco al arrancar, sin salida de crashIncompatibilidad del renderizador dmabuf, NVIDIA o AppImageWEBKIT_DISABLE_DMABUF_RENDERER=1 o el flag --safe-rendering
Ventana en blanco en cualquier hardware, sin salida de crashCombinación de GPU y driver desconocidaFlag --safe-rendering

AppImage o paquete nativo: no es lo mismo

El AppImage empaqueta su propio WebKitGTK; el .deb y el .rpm usan el WebKit del sistema. Esa diferencia decide qué fallos te pueden tocar.

El crash de colrv1_configure_skpaint es exclusivo del AppImage. La causa: el AppImage traía WebKitGTK compilado contra FreeType 2.11.1, pero no empaqueta libfreetype.so.6, así que WebKit carga la del sistema anfitrión. FreeType 2.13.0 añadió un campo a FT_ColorStopIterator y la estructura pasó de 16 a 20 bytes; en anfitriones con FreeType 2.13 o superior —Fedora 40 y posteriores— ese desajuste corrompe la aritmética de índices del renderizador COLRv1 de Skia y dispara la aserción. Los paquetes nativos no lo sufren.

La corrección fue subir el contenedor de build a ubuntu:24.04, con FreeType 2.13.2. Eso arrastra un efecto secundario que hay que conocer:

Versión del AppImageMínimo de glibcDistro más antigua soportada
v0.5.1 y anteriores2.35Ubuntu 22.04 LTS, Debian 12
v0.5.2 y posteriores2.39Ubuntu 24.04 LTS, Fedora 40 y superiores

Si estás en Ubuntu 22.04 LTS o Debian 12, no persigas el AppImage nuevo: instala el paquete .deb o .rpm más reciente. Los paquetes nativos usan el WebKit del sistema y no les afecta este cambio.

Como parche temporal antes de actualizar, puedes esconderle a Buzz las fuentes a color con una configuración de fontconfig:

mkdir -p ~/.config/buzz-fontconfig
cat > ~/.config/buzz-fontconfig/fonts.conf <<'XML'
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <include ignore_missing="yes">/etc/fonts/fonts.conf</include>
  <selectfont>
    <rejectfont>
      <pattern>
        <patelt name="color"><bool>true</bool></patelt>
      </pattern>
    </rejectfont>
  </selectfont>
</fontconfig>
XML
FONTCONFIG_FILE=~/.config/buzz-fontconfig/fonts.conf ./Buzz_*.AppImage

Ventana en blanco sin crash: el renderizador dmabuf

Afecta a GPUs NVIDIA —driver propietario y nouveau— y a instalaciones AppImage sobre cualquier GPU: la ruta de buffers sin copia de WebKitGTK es incompatible con algunas combinaciones de GPU, driver y compositor, y el proceso hijo de WebKit simplemente no pinta.

Buzz ya se defiende solo: antes de que WebKit inicialice, fija WEBKIT_DISABLE_DMABUF_RENDERER=1 automáticamente cuando detecta una GPU NVIDIA —leyendo el ID de fabricante 0x10de en /sys/class/drm— o cuando se está ejecutando como AppImage. Eso devuelve una ruta de render por memoria compartida, algo más lenta pero universal. La decisión se toma una sola vez por proceso: WebKit lee esas variables al arrancar y no hay interruptor en caliente.

Si la detección automática no basta, existe el flag manual:

./Buzz_*.AppImage --safe-rendering
# o en una instalación nativa:
buzz-desktop --safe-rendering

--safe-rendering fuerza a la vez WEBKIT_DISABLE_DMABUF_RENDERER=1 y WEBKIT_DISABLE_COMPOSITING_MODE=1, y vale solo para ese lanzamiento: no se recuerda entre ejecuciones. Si te resuelve el problema y lo quieres permanente, fija tú mismo la variable:

# ~/.bashrc o ~/.profile
export WEBKIT_DISABLE_DMABUF_RENDERER=1

Cuidado con mezclar ambas cosas: si tienes una variable de WebKit definida en el entorno y además pasas --safe-rendering, Buzz se niega a arrancar e imprime qué variable entra en conflicto. Son dos respuestas incompatibles a la misma pregunta y prefiere decirlo a elegir por ti. Quita la variable o quita el flag.

flowchart TD
    A["La ventana no pinta"] --> B{"¿Hay salida de crash con colrv1_configure_skpaint?"}
    B -->|Sí| C["Es el bug COLRv1 del AppImage"]
    C --> D{"¿Tu distro tiene glibc 2.39 o superior?"}
    D -->|Sí| E["Actualiza al AppImage v0.5.2 o superior"]
    D -->|No| F["Instala el paquete .deb o .rpm más reciente"]
    B -->|No| G{"¿GPU AMD RDNA4 con radv?"}
    G -->|Sí| H["Aplica las tres variables de la sección RDNA4"]
    G -->|No| I["Lanza con --safe-rendering"]
    I --> J{"¿Se arregla?"}
    J -->|Sí| K["Exporta WEBKIT_DISABLE_DMABUF_RENDERER=1 de forma permanente"]
    J -->|No| L["Captura la salida y abre un issue"]

AMD RDNA4 y ventana transparente

Afecta a GPUs AMD RDNA4, la serie RX 9000, con el driver radv. El síntoma es una ventana transparente o con corrupción gráfica. El apaño verificado por quien lo reportó son tres variables antes de lanzar:

export GDK_BACKEND=x11
export WEBKIT_DISABLE_DMABUF_RENDERER=1
export WEBKIT_SKIA_ENABLE_CPU_RENDERING=1
./Buzz_*.AppImage
# o en instalación nativa:
buzz-desktop

Cada una hace algo distinto:

  • WEBKIT_SKIA_ENABLE_CPU_RENDERING=1 fuerza a Skia a renderizar por CPU y esquiva el fallo de pintado de RDNA4 con radv.
  • GDK_BACKEND=x11 evita la ventana en blanco que aparece bajo un compositor Plasma-Wayland.
  • WEBKIT_DISABLE_DMABUF_RENDERER=1 previene la transparencia que aparece tras el primer pintado.

Una detección dedicada de RDNA4 está en seguimiento; por ahora esto es un apaño manual.

Cuando nada de lo anterior encaja

El procedimiento de diagnóstico que pide el proyecto:

# 1. Lanzar desde una terminal y capturar la salida
./Buzz_*.AppImage 2>&1 | tee buzz-crash.log

# 2. Buscar un volcado de núcleo
coredumpctl list | tail
coredumpctl info <PID>

Y luego probar --safe-rendering primero: si resuelve el problema, es una incompatibilidad de render de WebKit y el log ayudará a acotar qué driver está implicado. Con eso, se abre un issue indicando distro, GPU, versión del driver y la salida de terminal. Para confirmar que el proceso está vivo aunque no veas nada, ps aux | grep buzz basta.


Lista de verificación antes de seguir

  • Descargué el artefacto correcto para mi plataforma y arquitectura.
  • En Windows, superé SmartScreen e instalé Git for Windows con la opción de PATH correcta.
  • La app abre y pinta una ventana.
  • Sé a qué relay estoy conectado y de dónde sale esa URL.
  • La tarjeta de la barra lateral dice Connected.
  • Tengo nombre visible y envié un mensaje en #welcome-everyone.

Si algo falla por el lado del servidor —el relay no arranca, tu clave no está en el padrón de miembros, la comunidad no resuelve por su host— no lo pelees desde el cliente: eso pertenece al curso de administrador.


Resumen

  • Los artefactos son cuatro: Buzz_<version>_aarch64.dmg para macOS Apple Silicon, Buzz_<version>_x64.dmg para macOS Intel, Buzz_<version>_amd64.AppImage y Buzz_<version>_amd64.deb para Linux x86_64, y Buzz_<version>_x64-setup_alpha-unsigned.exe para Windows.
  • Para saber qué Mac tienes, mira About This Mac: Chip: Apple es Apple Silicon, Processor: Intel es Intel.
  • La build de Windows no está firmada: SmartScreen mostrará “Windows protected your PC” y se continúa con More info y luego Run anyway.
  • En Windows hay que instalar Git for Windows porque la herramienta de shell de los agentes corre bajo bash; BUZZ_SHELL apunta a otro shell y la descripción que ve el agente se actualiza sola.
  • El cliente usa ws://localhost:3000 por defecto. Precedencia: override elegido en la app, BUZZ_RELAY_URL, valor fijado al compilar, default.
  • Add community → Join an existing community acepta una URL de comunidad o un enlace de invitación; la URL se normaliza a ws/wss y se sondea con un límite de 4 segundos.
  • Sin relay propio: pide la URL a tu equipo, despliega uno en Railway con el botón del README, o remítete al curso de administrador.
  • El primer arranque crea o importa tu par de claves, pide nombre y avatar en dos pasos y te deja en general y welcome-everyone.
  • En Linux, una ventana en blanco casi siempre es WebKitGTK: el crash de colrv1_configure_skpaint es exclusivo del AppImage, --safe-rendering es el escape manual para ese lanzamiento, y en Ubuntu 22.04 o Debian 12 conviene el paquete nativo.

Siguiente: Tu identidad: claves, perfil y dispositivos