---
id: development-codex-live-session
title: Codex Live Session
category: development
version: 1.1
status: stable
audience:
  - administrator
  - operator
  - developer
  - ai
updated_at: 2026-07-18
related:
  - development-repository
  - operations-platform-operations
tags:
  - codex
  - tmux
  - ttyd
  - terminal
  - systemd
  - nginx
---

# Codex Live Session

## Arquitectura

Codex trabaja dentro de la única sesión tmux `aeos-dev`. El servicio ttyd adjunta un cliente web de solo lectura a esa sesión y escucha exclusivamente en `127.0.0.1:7681`. Nginx publica el transporte HTTP y WebSocket bajo `/development/terminal/live/`, mientras Spring Boot sirve la página `/development/terminal`.

```text
Codex -> tmux aeos-dev -> ttyd solo lectura -> Nginx -> /development/terminal
```

No existe escritorio gráfico, X11, VNC ni acceso directo a ttyd desde la red. La opción `--writable` de ttyd no se utiliza.

## Componentes instalados

- tmux 3.3a-3, instalado desde Debian 12 mediante APT.
- ttyd 1.7.7, binario oficial x86_64 instalado en /usr/local/bin/ttyd después de verificar SHA256SUMS.

La dependencia nativa libevent-core-2.1-7 es instalada automáticamente por APT para tmux. No se instala ningún escritorio, servidor gráfico o servicio de escritorio remoto.

## Funcionamiento

`aeos-dev.service` ejecuta un script idempotente al arrancar. Si la sesión exacta `aeos-dev` existe, la reutiliza; si no existe, crea una sola sesión con `/opt/esp-platform/repo` como directorio de trabajo. tmux mantiene la sesión aunque no haya clientes conectados.

`esp-platform-ttyd.service` depende de la sesión y ejecuta ttyd como el usuario `codex`. El navegador solo recibe la salida de terminal y no puede escribir, pegar, enviar teclas ni interrumpir procesos.

## Conexión

La vista HTTPS normal está disponible en:

```text
https://iot.aeizoon.com/development/terminal
```

Para trabajar desde SSH dentro de la misma sesión:

```bash
tmux attach-session -t aeos-dev
```

Para salir sin detenerla, use la secuencia tmux `Ctrl+B`, seguida de `D`.

## Operación

Comprobar o recrear la sesión si falta, sin duplicarla:

```bash
sudo systemctl restart aeos-dev.service
```

Reiniciar la publicación web sin detener tmux:

```bash
sudo systemctl restart esp-platform-ttyd.service
```

Consultar estado y logs:

```bash
systemctl status aeos-dev.service esp-platform-ttyd.service
journalctl -u esp-platform-ttyd.service -n 100 --no-pager
```

## Verificación

```bash
tmux list-sessions
systemctl is-active aeos-dev.service esp-platform-ttyd.service nginx
ss -ltnp | grep 7681
curl -I http://127.0.0.1:7681/development/terminal/live/
curl -I http://127.0.0.1:88/development/terminal
```

Debe existir exactamente una sesión `aeos-dev`; ttyd debe escuchar solo en `127.0.0.1:7681`; la página debe responder a través de Nginx. El servicio ttyd no debe contener `--writable` ni `-W`.

## Configuración versionada

- `scripts/ensure-aeos-dev-session.sh`: creación idempotente de la sesión.
- `infrastructure/systemd/aeos-dev.service`: persistencia tras reinicio.
- `infrastructure/systemd/esp-platform-ttyd.service`: ttyd de solo lectura.
- `infrastructure/nginx/codex-live-session.conf`: proxy WebSocket.

Los archivos efectivos se instalan en `/etc/systemd/system/` y en el sitio Nginx de ESP Platform. Los cambios se realizan primero en el repositorio y después se despliegan.

## Política de redimensionado

La sesión utiliza la política global `window-size largest` de tmux 3.3a y mantiene `aggressive-resize off`. Con varios clientes conectados, la ventana toma las dimensiones del cliente más grande; una conexión SSH de 80x24 no puede reducir la vista web.

ttyd fija `fontSize=18` y `lineHeight=1.35`. El navegador permanece en modo de solo lectura porque ttyd no se inicia con `--writable` ni `-W`. El cliente tmux no usa `attach-session -r`: tmux 3.3a excluye los clientes de solo lectura del cálculo de tamaño y eso impediría que la vista web aportase sus dimensiones a `window-size largest`.

La página reajusta xterm.js tras la carga del iframe, una recreación del terminal, cambios del contenedor, cambios de pantalla completa y redimensionados de la ventana. Se usa `ResizeObserver`, con dos reintentos cortos después de cada evento; no existe un bucle periódico de redimensionado.

Durante una caída del WebSocket la vista puede mostrar temporalmente el estado de desconexión. Al reabrirse la conexión, ttyd conserva o recrea el terminal y el observador vuelve a ajustarlo al contenedor.

Para verificar la política:

```bash
tmux show-window-options -g | grep -E 'window-size|aggressive-resize'
tmux list-clients -F '#{client_tty} #{client_width}x#{client_height} readonly=#{client_readonly}'
tmux list-windows -F '#{session_name} #{window_index} #{window_width}x#{window_height}'
```
