Estoy preparando un curso sobre planes de mejora. Al sentarme a montar la primera sesión me encontré con lo de siempre: lo que tengo que enseñar no son siempre todo ideas mías, también hay páginas web. El portal del INEE, el Education and Training Monitor de la Unión Europea, los informes de la OCDE, el apartado de documentos de centros de la conselleria,… Sitios vivos, que se actualizan, y que quiero que la gente vea funcionando.
Con una presentación al uso eso se resuelve de dos maneras, las dos malas. O haces capturas de pantalla —y entonces lo que enseñas es la foto de una web: no se puede pinchar, no se puede buscar dentro, y caduca el día que la conselleria cambie la página—, o abres veinte pestañas y te pasas la sesión buscando cuál era mientras la sala espera.
Hay una tercera, y es de una sencillez que da rabia no haberla tenido antes: que la diapositiva sea la página.
Present
Present es una aplicación de macOS en la que cada diapositiva es una dirección web. Pulsas para avanzar y lo que aparece a pantalla completa no es una imagen de la web: es la web, cargada y navegable, con sus enlaces y su buscador. Si a mitad de sesión alguien pregunta «¿y eso dónde lo pone exactamente?», se pincha y se enseña, sin salir de la presentación ni buscar la pestaña.
La escribió Simon Willison como demostración para una charla. Él mismo avisa en el repositorio de que está vibe coded: escrita del tirón con ayuda de un modelo, sin más pretensión que funcionar aquel día. Me la encontré, vi que resolvía justo mi problema, y llevo desde entonces convirtiéndola en algo que me atrevo a poner delante de gente. Esto es lo que le he añadido.
👉 Descargar Present 2.0 para macOS · código en GitHub (licencia Apache 2.0) · el original de Simon Willison

Preparar la sesión
Lo primero que hacía falta era todo aquello que convierte una lista de enlaces en algo que aún se entienda dentro de dos meses.
- Nombres. Una diapositiva puede llamarse «INEE» aunque su dirección tenga ochenta caracteres. Una lista de URLs en crudo no hay quien la lea.
- Varias listas. Cada curso y cada charla, la suya. Se cambia de una a otra con un desplegable, y la aplicación reabre donde lo dejaste.
- Diapositivas de texto. No todo es una web: la portada, los títulos de sección, el «gracias» del final. Se escriben en Markdown y las dibuja la propia app. La idea la tomé del fork de kcarnold; la implementación no, porque aquella mete el texto dentro del HTML tal cual y basta un
<o un&en tu diapositiva para romper la página. - Guardar sin perder nada. La lista vive en un archivo, en JSON o en texto plano, y ninguno de los dos formatos se deja nada por el camino: nombres, diapositivas de texto y el nombre de la lista sobreviven a la ida y la vuelta. Los
.txtsiguen siendo intercambiables con la app original y con la de kcarnold, así que un archivo hecho en una se abre en la otra.

Presentar de verdad
La otra mitad del trabajo es lo que pasa cuando ya estás de pie y hablando, que es donde una demo se distingue de una herramienta.
- El mando físico funciona. Esos cacharritos que se llevan en la mano envían «página arriba» y «página abajo», y la app original no los escuchaba: un clicker no hacía absolutamente nada. Ahora sí.
- La tecla
Bpone la pantalla en negro, para cuando quieres que la sala te mire a ti y no a la diapositiva. Se vuelve con la misma tecla. - Eliges en qué monitor se presenta, si hay más de uno conectado. Antes salía donde cayera.
- La siguiente diapositiva se va cargando mientras hablas. Avanzar ya no es un rectángulo blanco rellenándose delante de todos, sino una página que ya estaba ahí. Y si vuelves atrás, la encuentras donde la dejaste, con el scroll incluido.
- Las flechas arriba y abajo y la barra espaciadora se dejan a la página, a propósito. Muchas de mis diapositivas son artículos largos que hay que recorrer; avanzar se hace con las flechas laterales.
El mando del móvil, y por qué ahora lleva llave
Present levanta un pequeño servidor dentro del Mac que sirve una página para el móvil: adelante, atrás, arrancar, parar, zoom y una tira para hacer scroll. Escaneas un código QR con el teléfono y ya tienes mando a distancia sin comprar nada.

Al mirarlo de cerca resultó que ese servidor aceptaba cualquier cosa que le llegara. Cualquier página abierta en cualquier navegador de mi propio Mac podía adelantar mis diapositivas con una línea de JavaScript; el navegador bloquearía la respuesta, sí, pero la diapositiva ya se habría movido. Y cualquiera en la misma red podía hacer lo mismo.
Ahora cada endpoint pide una llave que se genera al arrancar la app, no se guarda en ningún sitio y muere al cerrarla. El código QR la lleva dentro —nadie teclea treinta y dos caracteres en un móvil— y la página la borra de la barra de direcciones nada más cargar, para que no salga en una captura de pantalla. También se puede apagar el mando del todo desde la app.

Cuento esto con detalle porque me parece la parte más instructiva de todo el asunto: el código escrito de un tirón funcionaba. Hacía exactamente lo que prometía. Simplemente, nadie le había preguntado qué pasaba si quien llamaba a la puerta no eras tú.
Cómo probarla
Hace falta un Mac con macOS 14 o posterior. Lo más rápido es bajarse Present-2.0.dmg, abrirlo y arrastrar la app a la carpeta Aplicaciones. La primera vez hay que abrirla con clic derecho > Abrir: la app no está firmada ni notarizada, así que si haces doble clic macOS se niega.
Y si prefieres compilarla tú, con Xcode instalado son tres órdenes:
git clone https://github.com/JLMirallesB/present.git
cd present
./scripts/build-app.sh --open
El repositorio guarda también las pruebas, así que ./scripts/test.sh te dice en dos décimas de segundo si lo que acabas de compilar está sano.
Lo que no hace (y conviene saber antes)
- Es solo para macOS. Está escrita en SwiftUI y no hay versión para Windows ni para Linux, ni la va a haber.
- Sin conexión no hay diapositivas. Si lo que enseñas son páginas web y la sala no tiene red, no tienes presentación. Las diapositivas de texto son lo único que sobrevive. Para una sesión con red dudosa, sigue siendo más prudente un PDF.
- El permiso para escribir el archivo dura lo que dura la sesión. La app corre en el sandbox de macOS, y el permiso que te da el sistema al elegir un archivo no sobrevive al cierre del programa. Al reabrir, la primera vez que guardas te vuelve a preguntar dónde.
- El mando lo maneja quien tenga el enlace. La llave protege de quien no lo tiene, no de quien sí. Trátalo como tratarías el clicker: no lo dejes por ahí.
Cómo está hecha
La he desarrollado con ayuda de Claude, igual que las otras herramientas que voy publicando por aquí, y creo que este caso ilustra bien una cosa que me interesa cada vez más: la diferencia entre escribir código con un modelo y mantener código con un modelo.
El original funcionaba. Pero al examinarlo aparecieron cosas como que la lista de presentaciones decía guardarse y no se guardaba, o que teclear un guion dentro de una página web durante la presentación cambiaba el tamaño de la letra. Fallos que una demo no nota porque nadie la usa dos veces.
El código está publicado con licencia Apache 2.0: se puede usar, modificar y reutilizar sin pedir permiso. Si lo pruebas y algo falla, se rompe o no se entiende, me interesa mucho saberlo —en los issues del repositorio o escribiéndome directamente.


Deja un comentario