pm
pm run -- npm run dev mete el proceso en una unit de systemd, descubre solo el puerto que abrió, resuelve colisiones y publica proyecto.localhost vía Caddy. Un core, cuatro caras: CLI, web, API HTTP y 13 tools MCP. Construido para WSL2 + systemd + Chrome.
El puerto 3000 lo quieren todos. pm le da a cada proyecto un nombre y se ocupa él del puerto.
Un binario Go que sabe qué corre en qué puerto, arranca y para proyectos de cualquier stack y los publica como proyecto.localhost. Lo usan personas por CLI y web, y agentes por MCP, con los mismos verbos.
De un comando en la terminal a un nombre en el navegador
Pulsa los pasos o deja que avance. Cada paso ilumina la pieza de la que habla.
La versión mínima que funciona: el mismo comando de siempre, con un prefijo delante.
Un core, cuatro caras
CLI, dashboard web, API HTTP y servidor MCP son proyecciones de la misma capa internal/api. Una feature se implementa una vez y aparece en las cuatro.
Una mañana con tres proyectos y un contenedor
Un caso inventado con números pequeños, para ver qué pasa en cada tramo antes de hablar de los retos.
pm run -- pnpm dev. No hay registro: scan ve next en package.json y guarda un borrador con puerto 3000 y estrategia -p. Arranca pm-tienda.service, el detector ve el LISTEN en 3000 y Caddy publica tienda.localhost.port 3000 taken → using 3001 e inyecta -- -p 3001. landing.localhost funciona igual. Ana no abrió ningún fichero de configuración.manage.py runserver el puerto va posicional: 0.0.0.0:8000. El stack lo decide, no Ana. api.localhost queda enrutado.pm claim 8080 lo adopta y desde ese momento tiene nombre y botón de stop.systemctl --user stop pm-landing se lleva pnpm, node y sus workers de una vez. Antes de cerrar, pm promote api: la unit pasa a permanente y arrancará sola al siguiente boot.pm_list antes de asumir que un puerto está libre, arranca tienda con pm_start en vez de improvisar un dev server en segundo plano, y lee pm_logs cuando algo no levanta.Cinco veces en que la solución obvia estaba mal
Cada reto sigue el mismo patrón: lo que cualquiera haría primero, por qué no sirve, lo que se hizo y el número que lo resume. El detalle técnico queda plegado.
Toda la herramienta responde esa pregunta para la máquina entera, y la responde igual a una persona en la terminal, a una pestaña del navegador y a un agente por MCP. Lo que ya resuelve el sistema (systemd, Caddy, Chrome con
*.localhost) no se reimplementa.Un solo filtro: ¿esto ya lo hace el sistema?
Si la respuesta era sí, se usó el sistema. Si no, se escribió lo mínimo y se dejó una costura para probarlo con fakes.
Profundizar
pm promote y pm demote son un cambio de tipo de unit, no una máquina de estados propia. Desde Windows, un shim pm.cmd en el PATH reenvía a wsl.exe -e pm; pm ui y pm open abren el Chrome de Windows en pm.localhost.
*.localhost lo resuelve Chrome solo, y un proxy en :80 dentro de WSL convierte tienda.localhost en el puerto real. Caddy ya sabe recargar configuración por su admin API sin cortar conexiones; escribir eso a mano sería mantener un reverse proxy dentro de un gestor de puertos.Profundizar
El daemon reconcilia el Caddyfile con el estado en cada cambio y Reload es un no-op silencioso si Caddy no está instalado: todo lo demás sigue funcionando por puerto. PM_NO_PROXY=1 lo desactiva para daemons secundarios y tests.
:2019.go:embed. Editar, make build, listo. El tiempo real va por SSE, no por polling: estado, start/stop, promote/demote, logs en streaming, adopción de listeners unmanaged, grupos y CRUD completo. El tono es el de una pestaña siempre abierta con una tabla viva.Profundizar
Un frontend con toolchain habría metido node en el build de un binario Go cuya gracia es instalarse con make install. El precio es un HTML a mano que crece; mientras quepa en una pantalla de código, compensa.
.mcp.json. Las 13 tools son los verbos de la CLI sobre la misma capa internal/api: un agente puede hacer exactamente lo que haría una persona en la terminal, sin una segunda implementación que derive.Profundizar
Transporte streamable HTTP con mark3labs/mcp-go. Lo que gana un agente es libertad real para operar procesos: comprobar qué corre antes de asumir que un puerto está libre, arrancar el proyecto en vez de improvisar un dev server en segundo plano, y leer los logs cuando algo no levanta.
*.localhost a servidores Node. pm nombra cualquier stack, resuelve colisiones y sincroniza Caddy desde el estado vivo, no desde un wrapper.