Compare commits

..
2 Commits
Author SHA1 Message Date
devopsandClaude Sonnet 5 410975f972 Merge branch 'docs/tmux-host-remote-control-continue'
Build and Push Docs Portal / Construir y publicar Docs Portal (push) Successful in 6m10s
Build and Push Docs Portal / Escaneo de Secretos (Gitleaks) (push) Successful in 31s
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QMP7ULbxbsB5g1vELNAT3D
2026-09-20 15:57:01 +00:00
devopsandClaude Sonnet 5 291db05a5e docs(tmux-host): documentar fix de Remote Control, --continue y patron de swap
Agrega tres gotchas nuevos a sesion-tmux-persistente.md, mismo estilo
que los existentes:

- Remote Control nunca se activaba solo: faltaba el flag
  --remote-control en launch_claude_in_session().
- Cada recreacion empezaba una conversacion en blanco: se agrego
  --continue al comando de lanzamiento.
- Actualizar tmux-host en caliente mata al proceso que hace el swap
  (corre dentro del propio contenedor): documentado el workaround de
  contenedor sibling via docker.sock.

Tambien actualiza la tabla "Que sobrevive a que" con una columna de
continuidad de conversacion, y el comando citado en la seccion de
healthcheck automatico.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QMP7ULbxbsB5g1vELNAT3D
2026-09-20 15:56:47 +00:00
@@ -230,11 +230,13 @@ falla:
contenedor.
- **Existencia de la sesión tmux `lab`** (`tmux has-session`): si no
existe, **sí se recrea automáticamente** (`tmux new-session -d -s lab
-c <WORKDIR>`, seguido de `tmux send-keys -t lab claude Enter` — ver
gotcha "sesión recreada pero sin Claude Code adentro" más abajo) — es
solo recuperar el propio entorno de trabajo del contenedor, no tocar
infraestructura externa, así que es seguro hacerlo sin intervención
humana. Si `WORKDIR` todavía no está montado (ver gotcha siguiente),
-c <WORKDIR>`, seguido de `tmux send-keys -t lab claude --remote-control
--continue Enter` — ver gotcha "sesión recreada pero sin Claude Code
adentro" más abajo, y los gotchas de Remote Control y `--continue`
agregados el 2026-09-20) — es solo recuperar el propio entorno de
trabajo del contenedor, no tocar infraestructura externa, así que es
seguro hacerlo sin intervención humana. Si `WORKDIR` todavía no está
montado (ver gotcha siguiente),
no se crea la sesión esa vuelta — se reintenta en el próximo ciclo en
vez de crearla mal posicionada.
@@ -301,14 +303,111 @@ en un contenedor descartable aparte (mismos mounts de `/DATA` y
`docker start` (arranque desde cero, no `restart`) recreó la sesión `lab`
con `claude` corriendo adentro sin intervención manual, en ~1 segundo.
## Gotcha: Remote Control nunca se activaba solo (2026-09-20)
Con la sesión `lab` recreándose sola y `claude` corriendo adentro (gotcha
anterior), quedaba un problema distinto y más sutil: la sesión servía
perfecto para trabajar vía `docker exec`/`lab-session.sh`, pero nunca
aparecía como controlable remotamente en claude.ai — como si Remote
Control jamás se hubiera activado.
**Causa raíz (confirmado en vivo 2026-09-20):** Remote Control es
opt-in por lanzamiento, vía el flag `claude --remote-control [nombre]`
de la CLI. Nada en `launch_claude_in_session()` lo pasaba nunca, así
que `remoteEnabled` en `~/.claude.json` quedaba en `false` para siempre
porque nadie lo pedía. No existe un paso separado de confirmación
"¿Activar Remote Control? y/n" más allá del diálogo normal de
confianza del folder (una hipótesis inicial de que sí existía tal paso,
y de que había una clave `remoteControlAtStartup` en `settings.json`,
resultó falsa al revisar directamente los archivos de configuración
reales).
**Cómo se detectó:** lanzar `claude --remote-control` a mano (en una
ventana de tmux en foreground, no vía un `!` de un solo uso que se
mata al terminar) sí registró la sesión y apareció en la lista de
sesiones activas de claude.ai como `zimaos-quizzical` — el hostname del
contenedor (`ZimaOS`) se usa como prefijo por defecto del nombre de
sesión remota.
**Fix:** cambiar la línea `tmux send-keys` en
`launch_claude_in_session()` para lanzar `claude --remote-control` en
vez de `claude` a secas.
**Validado en vivo:** tras reconstruir la imagen y swapear el
contenedor real (ver el gotcha del swap más abajo), `health.log`
registró `'claude --remote-control' lanzado...` al recrear la sesión, y
el pane de tmux mostró `/remote-control is active` con un link de
sesión válido — sin que nadie lo activara a mano.
## Gotcha: cada recreación de la sesión empezaba una conversación en blanco (2026-09-20)
Con Remote Control ya activándose solo, quedaba una fricción menor pero
molesta: cada vez que la sesión `lab` se recreaba (reinicio del NAS,
`docker rm` + recrear, o el propio healthcheck reaccionando a un
crash), `launch_claude_in_session()` arrancaba una conversación
completamente nueva. El contexto de trabajo en curso —no las
credenciales ni la confianza del folder, que sí persisten vía volumen—
se perdía cada vez, sin relación con los límites de cuota (ver la nota
al principio de este doc).
**Fix:** agregar `-c`/`--continue` (retoma la conversación más reciente
en el directorio de trabajo actual) al comando de lanzamiento:
`claude --remote-control --continue`. Si no hay ninguna conversación
previa en `WORKDIR`, el propio CLI arranca una nueva sin error — no
hace falta lógica condicional en el script.
**Validado en vivo — la prueba más fuerte posible:** el swap que
desplegó este mismo cambio (ver gotcha siguiente) mató la sesión de
Claude Code que lo estaba ejecutando. Del otro lado, la *misma
conversación* siguió sin cortarse, con el mismo ID de sesión, sin
ninguna intervención manual — evidencia directa de que `--continue`
efectivamente retoma la conversación y no solo que el contenedor volvió
a levantar.
## Gotcha: actualizar la imagen de `tmux-host` en caliente mata al propio proceso que hace el swap (2026-09-20)
Este contenedor tiene un problema estructural para actualizarse a sí
mismo: el proceso de Claude Code que ejecutaría `docker stop tmux-host
&& docker rm tmux-host && docker run ... tmux-host:nueva-imagen` corre
*dentro* del propio contenedor `tmux-host` — el primer `docker stop`
mata su propia shell a mitad de la secuencia, dejando el swap a medio
terminar (visto en vivo: un primer intento así falló en silencio).
**Fix:** correr la secuencia de swap desde un contenedor *sibling*
efímero, no desde dentro de `tmux-host`:
```bash
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /DATA/AppData/k3d-lab-v3/tmux-host:/tmux-host-cfg \
docker:cli sh /tmux-host-cfg/swap-retry.sh
```
Como este helper solo comparte el socket de Docker (no vive *dentro*
del contenedor `tmux-host`), detener y recrear `tmux-host` no lo afecta
a él ni al proceso que lo lanzó desde el host. El script
(`swap-retry.sh`, junto a sus logs, vive en
`/DATA/AppData/k3d-lab-v3/tmux-host/` — mismo path físico que
`/media/HDD-Storage/AppData/k3d-lab-v3/tmux-host/`, ver el gotcha del
symlink más arriba) deja un log fechado por corrida en `logs/` con el
`docker ps` y un `grep` sobre `healthcheck.sh` dentro de la imagen
nueva, para verificar sin tener que adivinar si el fix realmente quedó
adentro.
**Validado en vivo dos veces (2026-09-20):** el fix de Remote Control y
el de `--continue` se desplegaron cada uno con este mismo mecanismo,
ambos confirmados por `docker ps` (imagen e `CreatedAt` nuevos) y por
`health.log` mostrando la línea de lanzamiento esperada inmediatamente
después del swap.
## Qué sobrevive a qué
| Evento | ¿Sobrevive la sesión tmux (`lab`)? | ¿Sobrevive el login de Claude Code? |
|---|---|---|
| Corte de SSH / cerrar la terminal / cambiar de dispositivo | Sí — es exactamente el caso que este setup resuelve | Sí |
| `docker restart tmux-host` (reinicio del NAS) | **No al toque, pero se auto-recupera solo** — el proceso `tmux server` muere con el contenedor; `healthcheck.sh` la recrea en el próximo ciclo (máx. 30 min) sin intervención, o `lab-session.sh` la crea al instante si alguien se reconecta antes | Sí, vía el volumen montado en `/root/.claude` |
| `docker rm` + recrear el contenedor desde cero | No, pero igual se auto-recupera sola (mismo mecanismo de arriba) | Sí, vía el mismo volumen — no hace falta volver a autenticar ni reconfirmar el diálogo de confianza del folder (ver el mount de `claude-code-home.json`) |
| Falla de red real del host/NAS | N/A | N/A — `healthcheck.sh` la detecta y notifica, pero no la corrige (fuera de su alcance) |
| Evento | ¿Sobrevive la sesión tmux (`lab`)? | ¿Sobrevive el login de Claude Code? | ¿Retoma la misma conversación? |
|---|---|---|---|
| Corte de SSH / cerrar la terminal / cambiar de dispositivo | Sí — es exactamente el caso que este setup resuelve | Sí | Sí — el proceso `claude` ni se entera |
| `docker restart tmux-host` (reinicio del NAS) | **No al toque, pero se auto-recupera solo** — el proceso `tmux server` muere con el contenedor; `healthcheck.sh` la recrea en el próximo ciclo (máx. 30 min) sin intervención, o `lab-session.sh` la crea al instante si alguien se reconecta antes | Sí, vía el volumen montado en `/root/.claude` | Sí, desde el 2026-09-20 — `--continue` retoma la conversación más reciente en `WORKDIR` (ver gotcha arriba) |
| `docker rm` + recrear el contenedor desde cero | No, pero igual se auto-recupera sola (mismo mecanismo de arriba) | Sí, vía el mismo volumen — no hace falta volver a autenticar ni reconfirmar el diálogo de confianza del folder (ver el mount de `claude-code-home.json`) | Sí, mismo mecanismo — validado en vivo durante el swap de imagen del 2026-09-20 |
| Falla de red real del host/NAS | N/A | N/A — `healthcheck.sh` la detecta y notifica, pero no la corrige (fuera de su alcance) | N/A |
## Validación en vivo