Ghosty
Blog

El directorio que existe en tu máquina y no en la del agente

VS Code conectó con nuestro agente remoto cuando no había carpeta abierta, y falló cuando sí la había. El culpable era un solo campo de session/new — cwd — con una ruta que del otro lado del cable no existe.

5 min de lecturaFixter
  • agentes
  • ACP
  • protocolos
  • microVM
  • VS Code
  • Ghosty Teams
Aguafuerte de un embarcadero de ferry en Nueva York: la rampa articulada que salva el hueco entre el muelle y el barco
Ferry Slip, Edwin Kaufman, 1927 — Cleveland Museum of Art (CC0)

Nuestro puente de ACP nos salió barato porque no traduce: mueve líneas de JSON-RPC entre un WebSocket y la entrada estándar de un proceso, y nada más. Ésa era la tesis. Hoy encontramos el lugar exacto donde deja de ser cierta.

El síntoma que no tenía sentido

Conectamos VS Code —la extensión ACP Client, 0.2.0— contra un agente Goose v1.46.0 que corre en una microVM, a través de nuestro puente ghosty-acp, que es lo que convierte la dirección wss:// en un comando que un editor sí sabe lanzar.

Funcionaba. Y no funcionaba. Con VS Code abierto sin carpeta, la sesión arrancaba perfecta. Abriendo cualquier carpeta, moría al conectar con esto:

Failed to connect: Invalid params

Nada más. Ni el campo, ni la ruta, ni una pista.

El diagnóstico salió del canal Output

El error de la UI no sirve. La traza sí. En Output → ACP Client estaban los dos mensajes que importaban:

Lo que mandó el editor:

json
{ "jsonrpc": "2.0", "id": 2, "method": "session/new",  "params": { "cwd": "/Users/bliss/hola-mundo", "mcpServers": [] } }

Lo que contestó el agente:

json
{ "jsonrpc": "2.0", "id": 2,  "error": { "code": -32602, "message": "Invalid params",             "data": "invalid directory path" } }

initialize había respondido OK. El que revienta es session/new, y revienta por un solo campo: cwd.

El editor nombra una carpeta de tu disco. El agente la busca en el suyo.

La extensión lo arma así — cwd: t || void 0. Sin carpeta abierta manda undefined y el agente usa su propio directorio de trabajo. Con carpeta abierta manda una ruta de macOS. El agente la busca dentro de su propia microVM, no la encuentra, y contesta invalid directory path. Por eso el caso raro funcionaba y el caso normal no.

La premisa que ACP nunca hizo explícita

ACP se diseñó para que el cliente lance al agente como proceso hijo. Padre e hijo en la misma máquina, con el mismo filesystem. Bajo esa premisa cwd es trivial: es una ruta que los dos ven.

Nosotros rompimos la premisa a propósito —el agente vive aislado, con su propio disco y su propia terminal— y el protocolo no tiene dónde decirlo. cwd no es opcional ni negociable: viaja siempre, y siempre es literal.

No es un problema exclusivo de correr en la nube. Le pasa igual a quien tiene el editor en Windows y el agente dentro de WSL: mismo mensaje, mismo campo. En hermes-agent está reportado () y exactamente como había que arreglarlo: traduciendo el cwd al cruzar. Y en la spec hay un que ronda el mismo terreno sin cerrarlo.

Quién traduce: el que cruza la frontera

La respuesta no es "que el editor sepa de cajas" ni "que el agente adivine". Ninguno de los dos tiene por qué enterarse de que hay una red en medio; ése es el valor entero de un protocolo.

El que sabe que hay una frontera es el puente, porque él es la frontera. Es el único punto del camino donde una ruta del lado del usuario y una ruta del lado del agente existen simultáneamente en el mismo proceso.

Y no es la primera vez que lo hacemos. Nuestro relé ya reescribe session/new para inyectarle los mcpServers que le corresponden a ese agente. Ese mensaje es el único lugar donde el transporte se permite meter mano: pasa una sola vez por sesión, es declarativo, y todo lo que trae describe el entorno, no el trabajo. Lo que viene después —los prompts, los eventos, el razonamiento en vivo— sigue pasando intacto.

cwd es exactamente esa clase de campo. Estaba en el mensaje correcto desde el principio; sólo faltaba mirarlo.

La ruta local no desaparece: vuelve por el canal donde sí tiene sentido, fs/*, que resuelve el editor en tu máquina. Lo único que se traduce es el directorio de trabajo.

Lo que aprendimos de la forma en que falló

Tres cosas que nos costaron el rato, en orden de utilidad:

El caso que funciona puede ser el degradado. "Sin carpeta abierta sí jala" nos hizo buscar el bug en la conexión durante un buen rato. undefined no probaba que el transporte estuviera bien: probaba que el agente estaba cayendo a su propio directorio porque el editor no le había dicho nada.

Un error de protocolo pierde el detalle al subir a la UI. El JSON-RPC traía "data":"invalid directory path", que apunta directo al campo. La barra de VS Code mostró Invalid params. Cuando un cliente ACP falla, la traza cruda es el único lugar donde vive el diagnóstico.

Un protocolo con supuestos implícitos se rompe justo donde los estiras. ACP no declara en ninguna parte "cliente y agente comparten filesystem", pero está horneado en cwd, en fs/read_text_file y en terminal/*. Los últimos dos son capacidades que el cliente declara —si no las tiene, no se usan—. cwd no: viaja siempre.

El veredicto

Un puente que "sólo cambia el cable" es un buen objetivo y una descripción incompleta. En cuanto los dos extremos dejan de compartir máquina, alguien tiene que traducir lo que sólo tiene sentido de un lado. Son pocos campos —hoy, uno— y viven en un solo mensaje. Vale la pena saber cuál es antes de que un usuario abra una carpeta.

Pruébalo gratis hoy

Sin código. Sin complicaciones. Crea tu agente y ponlo a trabajar en minutos.

Ghosty ® 2026. Todos los derechos reservados.