# Terminal web

Consola del VPS en el navegador que sigue viva aunque te desconectes: tmux dentro del servidor, con permisos por usuario.

Fuente: https://ardumaker.com/docs/terminal-web/

- Categoría: Servidores e infraestructura
- Estado: Disponible
- Requisitos: Un VPS activo de la empresa; Ser miembro de la empresa con acceso a ese VPS
- Herramientas MCP (Solo leen): `ver_historial_comandos_vps`, `leer_archivo_vps`
- Herramientas MCP (Escriben o modifican): `instalar_app`, `controlar_app`
- Herramientas MCP (Destructivas): `ejecutar_comando_vps`, `guardar_archivo_vps`

## ¿Qué permite hacer?

La terminal web abre una consola del VPS en el navegador. No es una sesión SSH efímera: es un servidor `tmux` que vive dentro del VPS, así que el trabajo sigue corriendo aunque se cierre la pestaña, se corte la red o se reinicie el backend.

- Hasta 5 terminales vivas por persona y por VPS; las de otra persona no gastan el cupo propio.
- Volver a engancharse a la misma terminal todas las veces que haga falta.
- Un admin elige el usuario de Linux (por defecto `root`) y ve todas las terminales del VPS; un miembro trabaja con su propio usuario y ve solo las suyas.
- Seleccionar y copiar con el mouse como en cualquier página, con prompt en colores y autocompletado.

## ¿Cuándo conviene usarlo?

- Tareas largas (un build, una migración, una descarga) que no se quieren perder si se cae la conexión.
- Revisar o arreglar algo a mano sin instalar un cliente SSH ni abrir el puerto 22.
- Dar acceso de consola a un miembro con su propio usuario de Linux, sin compartir `root`.

## ¿Cómo funciona en ArduMaker?

Al crear una terminal, el backend le manda al agente del VPS un script que:

1. instala `tmux` y `ncurses-term` si faltan;
2. escribe `/etc/ardumaker/tmux.conf` (sin barra de estado y con el mouse apagado, para que la selección la haga el navegador);
3. escribe `/etc/ardumaker/terminal.sh` con el prompt en colores y lo engancha una sola vez al final del `.bashrc` del usuario;
4. crea `/run/ardumaker/tmux/<id>/` con permisos 700 del usuario de Linux;
5. escribe la unidad `ardu-tmux-<id>.service` en `/run/systemd/system/` y la arranca.

La unidad propia es lo que hace a la terminal persistente: el agente del VPS se actualiza solo y, al reiniciarse, mata todo lo que cuelga de él. Con su unidad (`Type=oneshot`, `RemainAfterExit=yes`, `KillMode=process`) el `tmux` no depende del agente.

Para engancharse, el panel pide una credencial que dura 12 horas y abre un WebSocket con ella. La credencial es la llave del WebSocket, no la sesión: cuando vence se pide otra y se vuelve a la misma terminal.

Cada vez que se listan las terminales se reconcilia con el VPS: se le pregunta a `tmux` si la sesión existe y se compara el `boot_id` del sistema. Sesión ausente con otro `boot_id` es `perdida_por_reinicio` (se avisa); sesión ausente con el mismo `boot_id` es una terminal cerrada. Si el VPS no contesta, no se toca nada.

## ¿Qué cambia realmente?

| Archivo o unidad | Para qué |
| --- | --- |
| `/etc/ardumaker/tmux.conf` | Configuración común de tmux |
| `/etc/ardumaker/terminal.sh` | Prompt en colores, enganchado al `.bashrc` |
| `/run/ardumaker/tmux/<id>/` | Socket de la terminal, solo para su usuario |
| `ardu-tmux-<id>.service` | Unidad en `/run/systemd/system/`: desaparece con el reinicio |

Nada cierra una terminal sola: ni desconectarse, ni un tiempo de inactividad. Solo cerrarla desde el panel (o `controlar_app` con `close`) mata el `tmux` y libera el cupo.

## Quién ve y usa cada terminal

La terminal es de quien la creó. La de un admin suele correr como `root`; si un miembro pudiera engancharse a ella tendría una shell de administrador que no puede abrir por otra vía. Por eso un miembro ve y engancha solo las suyas, y para él una terminal ajena no existe (404).

| Acción | Admin | Miembro |
| --- | --- | --- |
| Elegir usuario de Linux | Sí (por defecto `root`) | No: el suyo |
| Ver terminales | Todas las del VPS | Solo las suyas |
| Cerrar | Cualquiera | Solo las suyas |

## Esquema

**Una terminal web**

```text
Navegador (xterm.js en el panel)
  ↓
WebSocket (credencial de 12 h)
  ↓
Backend de ArduMaker (valida permisos y dueño)
  ↓
Agente del VPS (engancha el pty)
  ↓
ardu-tmux-<id>.service (servidor tmux como el usuario de Linux)
```

## Resultado esperado

La terminal figura como `viva` en la lista, con su usuario de Linux, su dueño y la última vez que alguien se enganchó. Una terminal `perdida_por_reinicio` se sigue mostrando a propósito, para avisar que se perdió trabajo; se quita cerrándola.

## Errores y resolución

| Síntoma | Causa |
| --- | --- |
| 409 al crear | Se llegó al tope de 5 terminales en ese VPS |
| 403 al crear | Un miembro intentó elegir otro usuario de Linux: solo un admin lo elige |
| 500 al crear | El VPS no pudo levantar el tmux; el detalle viene en el mensaje |
| Prompt sin colores, `ls` sin colores o Tab que no completa | El `TERM` no existe en la base de terminfo del VPS o el shell no es bash |
| Un cambio de configuración no se nota | Las terminales ya abiertas siguen con lo viejo: hay que cerrarla y crear otra |

Para diagnosticar una terminal que se ve mal, se pega esto dentro de ella:

```sh
echo "TERM=$TERM"; echo "bash=${BASH_VERSION:-NO}"; echo "tmux=${TMUX:-NO}"
infocmp "$TERM" >/dev/null 2>&1 && echo "terminfo OK" || echo "terminfo FALTA"
grep -c ardumaker/terminal.sh ~/.bashrc; ls -l /etc/ardumaker/
```

> **INFO:** Si se escribe `exit`, tmux termina aunque la unidad de systemd siga figurando activa: por eso el estado se le pregunta a tmux y no a systemd.

## Relación con MCP

Un agente MCP no se engancha a las terminales: son de las personas que usan el panel y nada de lo que corre por MCP comparte estado con ellas. Sí puede abrir una terminal como app (`instalar_app` con `app_type: terminal`, con las reglas de su dueño) y cerrarla (`controlar_app` con `close`; la ajena solo si su dueño es admin).

Para ejecutar comandos, el agente usa `ejecutar_comando_vps`: un comando por llamada, con espera de 10 a 300 segundos, salida recortada a 20000 caracteres y el directorio de trabajo recordado entre llamadas. Los comandos que parecen destructivos (`rm -rf`, `mkfs`, `shutdown`, `DROP DATABASE`…) se rechazan con 409 salvo `confirmado=true`. Tope: 10 comandos por segundo por VPS.

- Lectura: `ver_historial_comandos_vps` (qué se ejecutó, quién y con qué resultado; se guarda 30 días, con secretos etiquetados tapados) y `leer_archivo_vps`.
- Escritura con riesgo: `ejecutar_comando_vps` y `guardar_archivo_vps`, marcadas como destructivas.

> **PRECAUCION:** Un trabajo largo no se deja en segundo plano con `nohup … &`: muere cuando se actualiza el agente. Se lanza en su propia unidad transitoria, por ejemplo `systemd-run --unit=trabajo-x --collect /bin/sh -c '…'`.

Referencia en [/mcp/docs](https://ardumaker.com/mcp/docs) y [/mcp/vps](https://ardumaker.com/mcp/vps).

## Funciones relacionadas

- [Servidores VPS](https://ardumaker.com/docs/vps/)
- [Usuarios Linux](https://ardumaker.com/docs/usuarios-linux/)
- [Servicios systemd](https://ardumaker.com/docs/systemd/)
- [Túneles SSH](https://ardumaker.com/docs/tuneles-ssh/)
- [Servidor MCP](https://ardumaker.com/docs/servidor-mcp/)
