Hay algo profundamente satisfactorio en los paneles split-flap. Esas pantallas mecánicas de aeropuertos y estaciones de tren donde los caracteres giran a través de paneles con un sonido distintivo de chasquido antes de aterrizar en la letra correcta. Convierten información mundana — un número de puerta, una hora de salida — en un pequeño evento.
Creamos Split-Flap Display, un simulador open source que recrea esta experiencia en el navegador. Envía mensajes a través de una API simple y míralos caer en su sitio con efectos de sonido procedurales y transiciones de color. Sin dependencias en el frontend, un único servidor Express en el backend.
Por qué lo creamos
Queríamos una forma visual de monitorizar lo que Claude Code está haciendo mientras trabaja de forma autónoma. La salida del terminal es funcional pero olvidable. Queríamos algo que pudieras poner en un segundo monitor, una tele en la pared o una tablet en tu escritorio — algo que haga el trabajo de la IA visible y tangible.
La metáfora del split-flap funciona perfectamente para esto. Cada llamada a herramienta se convierte en un evento de flip: "READING server.js", "EDITING auth.ts", "RUNNING npm test". Miras el panel y sabes inmediatamente qué está pasando. Cuando Claude termina, el panel muestra "TASK COMPLETE / READY".
Cómo funciona
Todo el sistema es un único servidor Node.js sin dependencias en el frontend. El display es puro HTML, CSS y JavaScript vanilla.
La rejilla
El display es una rejilla de 20 columnas × 8 filas. Cada celda es una unidad split-flap con una mitad superior, una mitad inferior y un carácter superpuesto. Cuando una celda necesita cambiar, cicla por caracteres aleatorios con un delay creciente (easing cúbico) antes de aterrizar en el objetivo:
function getDelay(step, totalSteps) {
const progress = step / totalSteps;
const eased = progress * progress * progress;
return 25 + eased * 200;
}
Cada flip dispara una animación CSS que añade una rotación 3D sutil, y opcionalmente un sonido de clic procedural sintetizado con la Web Audio API — una ráfaga de ruido para el transitorio del clic, más un oscilador sinusoidal para el golpe grave del cuerpo del flap.
Sistema de paleta de colores
Cada nuevo mensaje genera una paleta de colores fresca a partir de un tono base. Durante las transiciones, celdas aleatorias destellan con colores de la paleta mientras flashes ambientales recorren el panel. Cuando el flip termina, los marcadores de esquina brillan con el color de la paleta. Esto hace que cada llegada de mensaje se sienta como un evento, no solo una actualización de texto.
API Push
Enviar un mensaje es una única petición POST:
curl -X POST http://localhost:3420/api/message \
-H 'Content-Type: application/json' \
-d '{"lines": ["HELLO", "WORLD"]}'
El texto se convierte automáticamente a mayúsculas y se centra. Si una línea contiene dos o más espacios consecutivos, se trata como un par etiqueta-valor y se alinea a los extremos — "GATE B42" se convierte en "GATE B42", igual que un panel de salidas real.
Los mensajes se encolan automáticamente. Si llega un mensaje mientras el panel aún está girando, espera 3 segundos después de que termine el flip actual antes de mostrarse.
Sesiones
Cada ruta URL crea una sesión de display independiente. Abre /office y /tv en pantallas diferentes, y cada una recibe su propio flujo de mensajes vía Server-Sent Events:
http://localhost:3420/ → sesión por defecto
http://localhost:3420/office → sesión "office"
http://localhost:3420/tv → sesión "tv"
Las sesiones se crean cuando un espectador se conecta y se limpian después de 5 minutos de inactividad.
Dashboard
Abre /dashboard para ver todas las sesiones activas en una sola pantalla. La rejilla se ajusta automáticamente según el número de sesiones (1 = pantalla completa, 4 = 2×2, 9 = 3×3). A diferencia de los displays individuales que usan elementos DOM, el dashboard renderiza todo en Canvas para rendimiento — maneja más de 40 sesiones simultáneas sin problemas.
Cada panel es clickeable y muestra el nombre de sesión, la rejilla de caracteres con animaciones de flip, flashes ambientales y marcadores de esquina — todo renderizado a 60fps en un único Canvas por panel.
Integración con Claude Code
El directorio examples/ contiene scripts shell que se enganchan a los eventos de Claude Code. Añádelos a tu .claude/settings.json:
{
"hooks": {
"SessionStart": [{ "command": "bash examples/hook-session.sh" }],
"PreToolUse": [{ "command": "bash examples/hook-prompt.sh" }],
"PostToolUse": [{ "command": "bash examples/hook-notify.sh" }],
"Stop": [{ "command": "bash examples/hook-stop.sh" }]
}
}
El hook principal (hook-notify.sh) lee el JSON de PostToolUse desde stdin y formatea un mensaje descriptivo según la herramienta:
- Edit → "EDITING server.js"
- Read → "READING package.json"
- Bash → "RUNNING npm test"
- Grep → "SEARCHING auth pattern"
- Agent → "AGENT exploring codebase"
Cada usuario tiene su propia sesión (basada en $USER), así que múltiples desarrolladores pueden tener sus propios paneles corriendo simultáneamente.
Decisiones técnicas
Cero dependencias en el frontend. El display es JS vanilla con animaciones CSS. Nada de React, nada de build step, nada de bundler. Clonas el repo, ejecutas npm start y funciona. La única dependencia del backend es Express.
SSE sobre WebSocket. Los Server-Sent Events son más simples, unidireccionales (que es todo lo que necesitamos — el servidor empuja al navegador), y se reconectan automáticamente. Sin protocolo de handshake, sin frames de ping/pong.
Canvas para el dashboard, DOM para display individual. Los displays individuales usan elementos DOM porque las animaciones CSS de perspective y rotateX dan un efecto de flip 3D más convincente. El dashboard usa Canvas porque renderizar más de 40 displays basados en DOM sería un desastre de rendimiento.
Audio procedural. El sonido del clic se sintetiza en tiempo real con la Web Audio API en vez de reproducir un sample de audio. Esto significa cero latencia, variación natural (cada clic es ligeramente diferente) y ningún archivo de audio que cargar.
Cómo empezar
git clone https://github.com/cloudstudio/split-flap
cd split-flap
npm install
npm start
Abre http://localhost:3420 y ejecuta la demo:
bash demo.sh
La demo simula una sesión de Claude Code — 15 mensajes, 4 segundos entre cada uno. Mira el panel girar a través de "READING PACKAGE.JSON", "EDITING SERVER.TS", "RUNNING NPM TEST" y finalmente "TASK COMPLETE / READY".
Tiene licencia MIT, cero configuración y corre donde sea que corra Node.js. Ponlo en una Raspberry Pi, un monitor libre o una pestaña del navegador. Si usas Claude Code, los hooks lo hacen inmediatamente útil. Si no, la API es lo suficientemente simple para integrarse con cualquier cosa que pueda hacer un HTTP POST.