Running Emacs Agent Shell over TRAMP
This will be a short and sweet post. I'm working on something a bit longer about why Emacs is the perfect system for remote development, and why I think that's important, but I spent part of my Sunday afternoon debugging something that I don't want anyone else to have to figure out for themselves.
TL;DR, disable direct async processes for ACP,
and (maybe) set CODEX_PATH=codex in agent-shell-openai-codex-environment.
Fuller explanation to follow.
I'd like to be able to develop remotely over TRAMP for a variety of reasons. One of the salient motivations is better agent sandboxing. One convenient way to solve the myriad problems is to connect (e.g. over SSH) to a clean environment for all of your development work, rather than installing one of these agents in your regular environment which may have secrets you don't want the agent snooping at.
I've been using the excellent agent-shell which has a TRAMP plugin to support remote use.
However, I hit a few snags getting it to work in my environment.
Disabling TRAMP direct async
TRAMP direct async processes are one of the seemingly endless set of things you need to tune in order to get a truly fast TRAMP setup (especially for packages like Magit). This simply doesn't work though with ACP. The immediate cause of this seems to be that it uses a PTY which can echo requests back, breaking the JSON RPC protocol used by the Codex server (unlike some companies, OpenAI are at least shipping an open-source harness with programmatic access as a first-class feature).
Here's how it looks like in my Doom config:
( after! ( :and tramp acp )
( defadvice! +tramp--disable-direct-async-for-remote-acp-a ( fn &rest args )
:around #' acp--start-client
( if ( file-remote-p default-directory )
( letf! ((#' tramp-direct-async-process-p #' ignore ))
( apply fn args ))
( apply fn args ))))
Setting the CODEX_PATH
After I figured that out, I was still getting hard errors back from agent-shell
when trying it out on a FreeBSD remote buffer.
What happened is that, unless you explicitly set CODEX_PATH,
the ACP package tries to go through OpenAI's codex node package.
On FreeBSD, it ends up hitting this lovely error, because OpenAI have not published a Node package + "official" binary for FreeBSD. Which in their eyes means "abort; this platform isn't supported". There is in fact an up-to-date port though, so this is wrong and we need to bypass it.
The workaround is setting a variable in your Emacs environment:
( setq agent-shell-openai-codex-environment
'( "CODEX_PATH=codex" ) )
This tells the ACP library to simply search for codex in the path.
Which is probably what you want anyways.
Note that you can't hard-code this without risking breakage across macOS, FreeBSD, and Linux.
Final note: versions
ACP requires specific Codex binary versions, presumably because the API could change between releases. You need to make sure these are in sync.
Hope this saves somebody a few hours!