ide-host Host the desktop uses — runs on the remote machine as openidea-server. For using it, see Remote development over SSH.
Two crates have “remote” in their name but are different things. Remote development is
ide-host (rpc.rs, the
openidea-server binary) plus the client in src-tauri/src/remote_dev.rs. ide-remote is SFTP deployment and
run targets (running a configuration over SSH or in Docker from a local project).Pieces
The server
--stdioserves one desktop client over stdin/stdout. stdout carries the protocol, so logs go to stderr (filter withOPENIDEA_LOG).- Its state lives under
OPENIDEA_SERVER_HOME(default~/.openidea), inconfig/anddata/. Language definitions can be added inconfig/languages/. - An SSH exec channel gets a minimal environment, so on every start the server takes the login shell’s environment and adds the IDE-managed tools directory to
PATH. --versionprints the app version and the protocol version.
Installing it on the remote machine
The desktop picks the server binary for the remote OS and architecture (fromuname -sm): OPENIDEA_SERVER_BINARY if set, then <data dir>/server/<os>-<arch>/openidea-server, then the one next to the app when the platforms match; otherwise it downloads the release build for that platform once into its data dir. It uploads the binary into ~/.openidea/server/ on the remote host, one folder per version, keyed by a content hash, and removes other builds of that version. CI keeps a static Linux (musl) build working.
The protocol
JSON-RPC 2.0 withContent-Length framing (ide-jsonrpc), over the server’s stdio:
The protocol version is
PROTOCOL_VERSION in rpc.rs. Errors are IdeErrors carried as JSON in the JSON-RPC error message, so the frontend sees the same kind / message as for a local command.
Routing commands
The frontend doesn’t know whether a window is remote. Features callcommands.* as usual; the routing happens below the generated bindings:
src/platform/tauriCore.tsis what@tauri-apps/api/coreresolves to (a Vite alias). Itsinvokeasks the installed route first.- In a remote window,
src/platform/remote.tsinstalls a route that sends the commands listed in the session’scommandstoremote_invoke, and runs everything else locally. remote_invokereplaces eachChannelargument with{ "$channel": id }, forwards the call as aninvokerequest, and deliverschannelnotifications back to the rightChannel.eventnotifications are re-emitted to the window through the normal event sink.
open_project and close_project (opening a local folder leaves the remote one; closing drops the connection), system font listing, and client UI settings. Client settings (keymap, appearance, editor fonts and colours…) are listed in src/platform/clientSettings.ts; a global tooling setting is applied on both sides.
What runs where
Port forwarding
Forwarded ports go through the SSH connection. In a dev container, each connection to a forwarded port runsopenidea-server --connect localhost <port> inside the container (via docker exec) and pipes the connection through its stdin/stdout, so the container’s network is reachable the same way on every Docker setup.
Trust
Restricted mode works the same in remote windows: before forwarding a command that isn’t on the restricted-mode allowlist, the desktop asks the server whether the remote project is trusted, and the server authorizes everyinvoke again with Host::authorize_command. For a dev container of a folder the user already trusts, the desktop starts the server with that project folder marked trusted (OPENIDEA_TRUSTED_ROOT, never persisted).
The WSL and container transports run programs with arguments directly (wsl.exe --exec, docker exec); only fixed scripts reach sh -c, and every variable value is passed as a positional argument.
Making a command work remotely
- Implement it in
ide-host::ops::<domain>, taking&Hostand the window label, not Tauri types. - Register it with the server’s
Dispatcher(d.add("name", |c| async move { ... })inrpc.rsor theopsmodule), reading arguments withc.arg("…"). - Keep the desktop command a thin adapter over the same function.
Testing
crates/ide-host/tests/rpc.rs,remote_env.rs,remote_plugins.rs: the protocol and server behaviour.smoke/server.tsstarts a realopenidea-server --stdioand speaks the protocol to it;smoke/desktop.tsgives the frontend’s modules a Tauri runtime whose commands go to that server through the remote-development route. The run and debug smoke tests use it (see Smoke tests).