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". 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: https://iot.aeizoon.com/development/terminal Para trabajar desde SSH dentro de la misma sesión: 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: sudo systemctl restart aeos-dev.service Reiniciar la publicación web sin detener tmux: sudo systemctl restart esp-platform-ttyd.service Consultar estado y logs: systemctl status aeos-dev.service esp-platform-ttyd.service journalctl -u esp-platform-ttyd.service -n 100 --no-pager Verificación 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: 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}'