Qué cambió en 2026
Cuatro cosas, y ninguna es la tableta.
- Los CLI agénticos se volvieron remotos primero. Claude Code registra una sesión desde un host tuyo y la abres en una pestaña del navegador. Lo que hace el trabajo nunca fue el editor, así que el editor dejó de necesitar ser local.
- Los túneles de VS Code movieron el extension host a la máquina remota. Sobre un túnel, una pestaña del navegador recibe el set completo de extensiones de escritorio. Sobre SFTP recibe nada más el subconjunto de web extensions. La misma barra de direcciones, otro producto.
- Las VPN de malla hicieron alcanzable una caja de solo egreso. Sin regla de entrada, sin bastión, y aun así una sesión de SSH, porque la caja marcó hacia afuera primero.
- La capacidad spot chica de ARM se volvió lo bastante accesible para sostener el trabajo pesado. Así que la caja siempre encendida se queda chica a propósito.
La pregunta dejó de ser "¿puedo desarrollar en un iPad?". Ahora es "¿puedo reparar la máquina donde está mi agente, desde aquí?".
Qué necesitas
| Cosa | Por qué | Costo |
|---|---|---|
| Magic Keyboard Folio, o un Logitech Combo Touch | El trackpad es el requisito. Una terminal sin teclado físico es una demostración | Unos 250 USD de lista, más económico de terceros |
| Blink Shell | La terminal. Trae mosh, guarda las llaves en el Secure Enclave, tiene un comando code
|
Blink+ son 19.99 USD al año, con prueba de 14 días |
| La caja de la parte 1 | Donde viven Claude Code y el repo | Unos 12 USD al mes en t4g.small
|
| VPN de malla | Alcanzarla sin abrir un puerto | El plan gratuito alcanza |
| Monitor externo | Nada. Los iPads sin chip M solo espejan | No compres uno |
Empieza sin configurar nada
Abre claude.ai/code en Safari, escoge la máquina, trabaja. Agrégalo a la pantalla de inicio para que se comporte como app y no como pestaña. Si la caja de la parte 1 está corriendo, esto funciona ahora mismo sin instalar nada.
Hazlo antes de construir cualquier otra cosa. Te dice si la ergonomía te acomoda antes de gastar un fin de semana en el resto.
Luego fíjate en lo que no puede hacer: en esa pestaña no hay shell. Y ahí está todo el problema.
Si todavía no tienes caja
La versión durable es la parte 1. La versión corta, suficiente para seguir este post: una t4g.small sobre Ubuntu arm64, un instance profile con AmazonSSMManagedInstanceCore, y un security group sin ninguna regla de entrada.
AMI=$(aws ssm get-parameter --output text --query Parameter.Value \
--name /aws/service/canonical/ubuntu/server/24.04/stable/current/arm64/hvm/ebs-gp3/ami-id)
aws ec2 run-instances \
--image-id "$AMI" --instance-type t4g.small \
--iam-instance-profile Name=agent-box \
--security-group-ids "$SG" \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=30,VolumeType=gp3,Encrypted=true}' \
--metadata-options HttpTokens=required \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=agent-box}]'
Luego, en la caja, los dos paquetes de los que depende este post y un archivo de swap, porque 2 GB con un proceso de Node encima se quedan sin memoria:
sudo apt-get install -y tmux mosh
sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Pon todo eso en el script de bootstrap de la parte 1 en lugar de teclearlo una vez. Una instancia cuyo AMI viene de un parámetro de SSM se reemplaza con el tiempo, y el disco se va con ella.
Configura la tableta
Cuatro instalaciones, una sola vez.
1. El teclado. Magic Keyboard Folio para iPad (A16) si quieres el de Apple, Logitech Combo Touch si no. El requisito es el trackpad, no la marca. Seleccionar texto en una terminal con la yema del dedo es tan incómodo que dejas de hacerlo, y entonces dejas de leer bien la salida.
2. Blink Shell, del App Store. Blink+ son 19.99 USD al año con prueba de 14 días, y es la única pieza que cuesta dinero directo. Se lo gana porque trae mosh, guarda las llaves en el Secure Enclave y tiene un comando code. Termius y Secure ShellFish son alternativas razonables; Secure ShellFish monta el host remoto en la app Archivos, que es otro juego de concesiones.
Genera la llave dentro de Blink en lugar de copiar una llave privada al dispositivo:
config → Keys → + → Secure Enclave
Con Tailscale SSH no vas a necesitar instalar esa llave pública en ningún lado, porque la tailnet negocia la identidad. Genérala de todos modos: es a lo que recurres el día que apagues la VPN.
Luego agrega el host:
config → Hosts → +
Host: agent-box
HostName: agent-box (el nombre en la tailnet)
User: appuser
3. Tailscale, del App Store, con sesión en la misma cuenta que la caja.
4. claude.ai/code en la pantalla de inicio. Safari, Compartir, Agregar a inicio. Pierde la barra del navegador y se comporta como app. Instala también la app de Claude, para que el teléfono sirva de segunda pantalla cuando quieras ver cómo va una corrida larga.
Luego corre la prueba que de verdad te dice si esto funciona:
mosh appuser@agent-box
tmux new -A -s main
Arranca algo largo. Bloquea la tableta, espera un minuto, desbloquea, reconéctate con mosh appuser@agent-box y tmux new -A -s main. La sesión debe estar ahí con el trabajo todavía corriendo. Si está, la configuración quedó y todo lo de abajo es preferencia.
Las tres maneras de entrar
Esta es la parte que solo importa cuando la laptop está apagada.
1. La sesión del navegador
claude.ai/code en Safari. Cero configuración, sobrevive que cierres la pestaña, y aquí pasa la mayor parte del trabajo.
No tiene terminal. Así que cuando la caja necesita un humano, este camino no lo puede dar. Todo lo de abajo existe por esa frase.
2. Una terminal de verdad sobre la VPN de malla
En la caja:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --reset --ssh --hostname=agent-box
La caja marca hacia afuera, así que el security group se queda de solo egreso y nada escucha en internet. --ssh deja que la tailnet negocie la identidad de SSH, así que no hay llave pública que copiar a la tableta.
Tres detalles en ese solo comando:
-
Sin
--advertise-tags, a propósito. Un tag cuesta dos ediciones de política, no una. Hay que declararlo entagOwnerso el comando muere de entrada conrequested tags [tag:agentbox] are invalid or not permitted, y además taguear el nodo lo saca deautogroup:self, así que la reglasshpor defecto deja de aplicarle y necesitas una segunda condstapuntando al tag. Sin tag, el nodo es tuyo y las dos cosas salen gratis. La concesión es la expiración de llave: los nodos sin tag expiran, así que apágale la expiración a ese dispositivo en la consola. Los nodos tagueados no expiran, y ese es el argumento real para hacerlo por el camino largo más adelante. -
--resetporquetailscale upse niega a cambiar ajustes sin que vuelvas a mencionar todas las banderas no-default. Cualquier intento anterior deja banderas guardadas. -
--hostnameporque el default es el hostname de EC2, que cambia en cada reemplazo y te deja un nombre inservible en la tailnet.
Aun así necesitas una sección ssh en la política. Sin tag, apunta a tus propios dispositivos:
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["appuser", "autogroup:nonroot"]
}
]
Usa accept, no check. El check pide re-autenticar en el navegador cada cierto tiempo, que es incómodo desde una tableta.
Desde la tableta:
mosh appuser@agent-box
tmux new -A -s main
Todo vive dentro de tmux. iPadOS mata una app en segundo plano sin preguntar, y lo va a hacer a media tarea. mosh más tmux new -A -s main te devuelve la sesión exactamente como estaba, a través de la suspensión, un cambio de Wi-Fi y un traspaso de hotspot. El SSH pelón te devuelve un socket muerto y trabajo perdido. Esa sola regla es la mayor parte de la diferencia entre que esto se sienta profesional o se sienta como una concesión.
La -A importa más de lo que parece: entra si la sesión existe y la crea si no, así un solo comando sirve para conectar y para reconectar. Con tmux new -s main pelado el reconectar falla y acabas con main, main-1, main-2.
Y una trampa que va a parecer un bug de tmux y no lo es. Blink invoca ~/.local/blink/mosh-server antes del del sistema, y si no está, ese intento sale 127, Blink reintenta, y la sesión que acaba de morir se lleva tu servidor de tmux recién creado. El cliente entonces reporta:
error connecting to /tmp/tmux-1000/default (No such file or directory)
que te manda a depurar tmux, los permisos de /tmp y los locales, y ninguno es el problema. Un symlink elimina el intento fallido:
mkdir -p ~/.local/blink
ln -sf "$(command -v mosh-server)" ~/.local/blink/mosh-server
3. Session Manager en el navegador, como rompe-cristal
La consola de AWS da un shell en la instancia desde Safari, sin nada instalado en la tableta y sin VPN en el camino. Solo necesita el agente de SSM y el instance profile que ya creaste.
Es el camino que sigue funcionando cuando la configuración de la VPN está mal, y en la ventana justo después de que un reemplazo borró lo que hayas configurado a mano.
Verifícalo desde la tableta antes de necesitarlo, incluyendo el paso de MFA. Si el segundo factor vive nada más en la laptop que ahora está apagada en casa, este camino es decorativo. Son cinco minutos que no sirven de nada si los dejas para después.
Por qué las tres
| Camino | Configuración | Da un TTY | Sobrevive un reemplazo |
|---|---|---|---|
claude.ai/code |
Ninguna | No | Sí |
VPN de malla más mosh
|
Los dos lados, una vez | Sí | Solo si la instalación de la VPN está en el bootstrap |
| Session Manager | Nada más allá del instance profile | Sí | Sí |
La parte 2 terminó en una caja que estaba active y sin registrar. Recuperar una sesión de Claude Code en ese estado necesita una terminal interactiva, así que el camino cómodo es justo el que no puede. Dos de estos tres no son opcionales.
El editor
En la caja:
curl -Lk 'https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-arm64' \
--output vscode_cli.tar.gz
tar -xf vscode_cli.tar.gz
./code --version
./code tunnel --accept-server-license-terms
El primer arranque imprime un código y una URL que abres en la tableta. Después de eso tienes VS Code con tus extensiones reales, la de Claude Code entre ellas, porque el extension host corre en la caja.
Corre la descarga como el usuario de la caja, no como root. Hecha desde un shell de root, el binario queda en el home de ese usuario con dueño root y todo lo de después falla de formas que nunca mencionan los permisos.
Luego déjalo como servicio, en este orden:
sudo loginctl enable-linger appuser
./code tunnel service install --accept-server-license-terms
systemctl --user is-active code-tunnel
El enable-linger no es opcional y va primero. service install crea un servicio de usuario, y un servicio de usuario muere con el último login si el usuario no tiene linger. El síntoma sin eso es "el túnel desaparece cuando me desconecto", que no apunta a systemd.
Cuando el servicio esté arriba, mata el ./code tunnel que dejaste en primer plano en el paso anterior. Si lo dejas, quedan dos procesos peleando por el mismo nombre de túnel, y el que sobrevive una desconexión es el del servicio, no el tuyo.
Cuatro cosas que si no, te van a costar tiempo:
-
La carpeta tiene que ir en la URL.
https://vscode.dev/tunnel/<nombre>abre un editor sin archivos y parece roto. Lo que quieres eshttps://vscode.dev/tunnel/<nombre>/home/appuser/myapp. La forma relativa,/tunnel/<nombre>/myapp, funciona en unas versiones y en otras no; la de ruta completa falla menos. O abre la URL pelada y usa File, Open Folder una vez, y queda en Recent. -
code statussiempre va a decirNo installation of Visual Studio Code stable was found. Ese comando busca un VS Code de escritorio en la máquina, que no es lo que un túnel necesita ni algo que deba estar ahí. No es un error. Para revisar el túnel usacode tunnel service logosystemctl --user is-active code-tunnel. -
Diez túneles por cuenta. Pasando eso, el CLI borra uno sin usar al azar, así que limpia con
code tunnel unregister. -
El build de ARM es
cli-alpine-arm64y corre en Ubuntu. Verificado sobre glibc,code 1.140.0; no hace falta un userland musl ni una variante linux-arm64. Aun así corre./code --versionjusto después de extraer, porque una arquitectura equivocada falla ahí y no después, dentro de algo que parece un problema de túnel.
Desde Blink en lugar de Safari. El comando code de Blink abre el mismo editor sin salir de la app de terminal:
code <tunnel_url>
También tiene un modo SFTP que no necesita túnel, usando la extensión de filesystem de Blink:
code appuser@agent-box:~/myapp
Práctico para una edición rápida, con una cosa que conviene saber: en modo SFTP el extension host corre en el navegador, así que recibes solo web extensions y la de Claude Code no está entre ellas. El túnel es la ruta que te da el editor real.
Lo único que no se puede automatizar es la autenticación por dispositivo del túnel. El binario se instala desde un script, el token no, así que un reemplazo de instancia significa volver a registrarlo a mano. Al menos es un paso que sí se puede hacer desde la tableta.
Un servidor de VS Code más su extension host más Claude Code en 2 GB va apretado incluso con swap. Si el editor del navegador va a ser la interfaz principal y no algo ocasional, dimensiona la instancia un escalón arriba.
El trabajo pesado va en otro lado
La caja es chica a propósito. Las suites de pruebas que necesitan base de datos, los builds de contenedor y las pruebas de navegador van en CI, así que un push es la forma de correrlas. Si el proyecto ya se despliega por pipeline y no con builds locales, nada cambia cuando viajas, salvo quién levanta el contenedor.
Lo que no funciona
- Contenedores, una base de datos local, una suite de pruebas contra un Postgres real. iPadOS no da virtualización. No es un problema de permisos ni de encontrarle la vuelta.
- Una segunda pantalla. El escritorio extendido necesita M1 o posterior; todos los demás iPads espejan, así que un monitor te da una copia con barras negras de la tableta.
-
Tres pestañas del navegador haciendo todo esto a la vez. Con 6 GB de RAM las pestañas se desalojan. Escoge un cliente principal y deja el trabajo real en
tmuxdel otro lado.
La configuración está terminada cuando puedes reparar la caja desde la tableta, no cuando puedes programar en ella.
Top comments (1)