Navegando en el blogver navegación en todos los blogs
La skill markeup-devtunnel —«Publica el dev server en la LAN y por tunel HTTPS»— es una de las
habilidades que el sistema MarkeUP tiene escritas para Hermes Agent y para Cline.
Esta página es su ficha pública: lo que sabe hacer, cuándo se usa y qué comandos ejecuta.
Dos enlaces —la WiFi de casa y el túnel— y ningún despliegue: el sitio entero de MarkeUP abierto en el móvil con un solo comando.
El texto de la sección «Instrucciones del canon» está transcrito del fichero fuente —que se escribe sin tildes por convención de su propio gate—, así que es exactamente lo que lee el agente cuando le pides algo. La cabecera y esta entradilla sí están redactadas para leerlas.
| Dato | Valor |
|---|---|
| Skill | markeup-devtunnel |
| Responsabilidad | Publica el dev server en la LAN y por tunel HTTPS. |
| Versión | 1.0.0 |
| Autoría | uriszarernesto-blip · licencia MIT |
| Plataformas | linux · macos |
| Tags del canon | dev · tunel · lan · movil · astro · http |
| Skills relacionadas | markeup-cli · markeup-context · markeup-deploy |
| Fuente | ~/.hermes/skills/markeup/markeup-devtunnel/SKILL.md |
Responsabilidad unica: levantar el dev server de Astro escuchando en la LAN y asomarlo a internet por un tunel HTTPS hacia el mismo puerto, y devolver los dos enlaces (el de la red local y el publico) para testear el sitio desde el movil.
No escribe contenido, no valida y no publica: levanta dos procesos, comprueba que sirven de verdad
y los para. Lo que esta levantado queda apuntado en logs/dev-tunnel/state.json (puerto, pids y
enlaces), asi que cualquier llamada posterior sabe que hay ahi.
- Quieres ver el sitio en el movil sin desplegar.
- Un cambio de CSS, animacion, grafo o reproductor hay que probarlo en un dispositivo real.
- Alguien de fuera tiene que mirar una version en curso desde otra red.
- Necesitas saber si el dev server sigue vivo:
npm run dev:tunnel:status(exit 0 = si). - Un
/goalnecesita un gate verificable:dev:tunnel:statuslo es (mira el proceso Y el HTTP).
No lo uses para publicar (eso es markeup-deploy) ni para validar contenido (eso es el gate
npm run verify:content).
Se pide en objetivos, en lenguaje natural; el comando lo pones tu. Estas frases caen aqui directas
(la tabla completa vive en SOUL.md, seccion «Frases naturales → accion»):
| Lo que se dice | Lo que se hace |
|---|---|
| «levantame el server para el movil» | npm run dev:tunnel y devuelves los dos enlaces |
| «pasame el enlace para verlo desde fuera» | npm run dev:tunnel -- --notify (los enlaces al chat) |
| «¿sigue vivo el server?» | npm run dev:tunnel:status y respondes con su salida real |
| «paralo» · «ya lo he visto» | npm run dev:tunnel:stop |
Con algo ya levantado, repetir el comando es lo correcto: devuelve los mismos enlaces en vez de reiniciar. Una frase ambigua («levantalo», sin decir que) se aclara preguntando el dato que falta, no arrancando procesos a ciegas.
| Acceso | Para quien | Que hace falta |
|---|---|---|
http://<ip>:<puerto> (LAN) | el movil en la misma WiFi | nada: la IP sale de la ruta por defecto del sistema |
https://<aleatorio>.<dominio> | cualquiera, desde cualquier red | un tunel usable (ssh y npx ya vienen) |
npm run dev:tunnel # LAN + el primer tunel disponible (por defecto)
npm run dev:tunnel:setup # diagnostico: que IP y que tuneles hay (no levanta nada)
npm run dev:tunnel:status # ¿siguen vivos? (exit 0 = si: el gate de /goal)
npm run dev:tunnel:stop # para el dev server y el tunel
npm run dev:tunnel -- --tunnel none # solo LAN, sin salir a internet
npm run dev:tunnel -- --notify # ademas, manda los enlaces al chat de Telegram
npm run dev:tunnel -- --restart # para lo que hubiera y vuelve a levantar
Flags, salidas y ficheros al detalle: references/command-reference.md.
- El orden manda: primero el tunel (su host es un argumento del dev server) y despues el dev server. Al reves no hay host que permitir y la URL publica responde 403.
- Al dev server se le pasa el host EXACTO del tunel (
--allowed-hostsde Astro 7): no se tocaastro.config.mjs, asi que unnpm run devnormal sigue cerrado alocalhost. - Nada de esto toca el vault: no escribe en
src/content/posts/, no commitea y no publica. - Pararlo antes de publicar: con el dev server vivo,
npm run content:cacheno borra la cache de render del build (lo avisa y sigue), asi quenpm run dev:tunnel:stopva antes delbuild. - Un tunel no prueba la build: sirve el dev server. Para validar la build,
npm run preview.
| Trampa | Sintoma si se ignora |
|---|---|
Vite valida la cabecera Host y rechaza el dominio del tunel | la URL publica responde 403 «Blocked request» mientras la LAN va bien |
astro dev se manda solo a segundo plano cuando huele a agente | matas el proceso que lanzaste y el servidor sigue escuchando |
Por eso el script lo lanza con ASTRO_DEV_BACKGROUND=1 (el servidor es hijo suyo, con su grupo de
procesos y su log) y mata por grupo (npm run dev es un arbol: npm → sh → node astro).
| Orden | Proveedor | Requiere | Instalar | Pega |
|---|---|---|---|---|
| 1 | cloudflared | el binario | brew install cloudflared | ninguna: HTTPS limpio y sin cuenta |
| 2 | ngrok | el binario + authtoken | brew install ngrok | la cuenta gratis interpone una pagina de aviso |
| 3 | localhost.run | ssh (ya viene) | — | la URL cambia en cada arranque y necesita salida al puerto 22 |
| 4 | localtunnel | npx (ya viene) | — | la primera visita pide la IP publica de la maquina como contrasena |
En auto se prueba esa cadena en orden y se queda con el primero que dé URL. Si ninguno está, el
script lo dice y deja solo la LAN; nunca inventa un enlace publico. Alias que acepta --tunnel:
cloudflare, tunnel, lhr, localhostrun, lt, none, no, off, sin.
El estado pasa por cuatro fases y se escribe en cada una (arrancando → tunel → dev →
listo). Esa escritura incremental es deliberada: si el script muere a medias, --stop tiene los
pids apuntados y recoge los dos procesos igual.
npm run dev:tunnel:status # ¿proceso vivo Y HTTP < 400? Avisa si la fase no es `listo`
npm run dev:tunnel:status -- --json # lo mismo en JSON, para una maquina
npm run dev:tunnel:stop # mata tunel y dev server, y borra el estado
Repetir npm run dev:tunnel con algo levantado no reinicia nada: repite los enlaces. Para
reiniciar de verdad, --restart. Un astro dev ajeno (sin tunel) se para para poder permitir el
host del tunel; con --keep el script falla en vez de tocarlo.
- La URL del tunel puede rotar (sobre todo en
localhost.run):--statuslee el log del proveedor, detecta la URL nueva y lo dice;npm run dev:tunnel -- --restartla toma y la reenvia. - 403 en la URL publica: el host permitido no es el del tunel.
--restart. - El enlace LAN no responde desde la propia maquina: suele ser el cortafuegos de macOS (Ajustes → Red → Cortafuegos), y entonces el movil tampoco entra.
- El primer arranque tarda:
astro devcompila el vault entero. El estado se escribe antes de esperar, asi que un--statusen ese rato dice la verdad. - Cerrar la terminal no lo para: los procesos nacen
detached. Se para con--stop.
cd ~/markeup
npx vitest run scripts/mjs/lib/dev-tunnel.test.mjs # contrato del reconocimiento (IP, URL del tunel)
npm run dev:tunnel:setup # ¿que IP y que tuneles hay en esta maquina?
Prueba de extremo a extremo (medida el 2026-10-10, localhost.run): dev:tunnel dio la URL publica
y la LAN, la publica respondio 200 sirviendo MarkeUP, un Host ajeno respondio 403, y
--status, --status --json y --stop dejaron limpio el puerto y el proceso.
references/command-reference.md— todas las flags, los codigos de salida, el JSON de estado y el diagnostico de fallos.markeup-cli— el resto de la CLI del proyecto.markeup-deploy— publicar de verdad (lo que este script no hace).- Guia de uso en llano (post publico):
Documentación/doc-dev-tunnel.md(/doc-dev-tunnel) — el paso a paso con lo que se ve en pantalla, cuando abrir la WiFi y cuando el tunel, y el diagnostico de fallos para el usuario final. La explicacion tecnica del sistema:docs/dev-tunnel.md.
¿Quieres saber cómo se piden estas cosas? La guía completa está en skills de Hermes Agent, con la chuleta de objetivos y los casos paso a paso.
Dev server y túnel
Explora las ramas del artículo
