Remote jcode (cross-machine)
Drive a jcode session running on another machine from this one, over the
WebSocket gateway (crates/jcode-base/src/gateway.rs).
Verified working: Linux client -> Windows 11 host over Tailscale, including
remote bash tool execution, ~10ms WebSocket upgrade.
Setup on the host (the machine that runs the session)
From inside jcode, /remote does all of this:
/remote on # enable the gateway
# then restart the server: jcode server reload
/remote pair # pairing code + QR
/remote # status, dial address, paired devices
/remote revoke <device>
The equivalent by hand:
-
Enable the gateway in
~/.jcode/config.toml(Windows:%USERPROFILE%\.jcode\config.toml):[gateway] enabled = true port = 7643 bind_addr = "0.0.0.0"JCODE_GATEWAY_ENABLED=1works as an env override. -
Restart the server so it picks up the config:
jcode server reload # or: jcode server stop --force && jcode server startConfirm it bound:
curl -s http://127.0.0.1:7643/health -
Generate a pairing code (valid 5 minutes):
jcode pair
Setup on the client
python3 scripts/remote/remote_check.py --host <host-ip> --code 123456 \
--working-dir '/path/on/remote'
The token is cached in ~/.jcode/remote-tokens/<host>_<port>.json (mode 600),
so later runs omit --code.
Gotchas found in practice
-
Windows Firewall silently wins. Auto-created inbound block rules for
jcode.exe(created when someone dismisses the Windows network prompt) override any allow rule you add./healthwill answer on the host itself and time out from outside. Find and remove them:Get-NetFirewallRule -Direction Inbound -Action Block -Enabled True | Where-Object { ($_ | Get-NetFirewallApplicationFilter).Program -like '*jcode*' } | Remove-NetFirewallRuleThen allow the port, scoped to the Tailscale CGNAT range rather than the world:
netsh advfirewall firewall add rule name="jcode-gateway-tailscale" ` dir=in action=allow protocol=TCP localport=7643 remoteip=100.64.0.0/10 -
bind_addr = "0.0.0.0"is not authentication. Anything that can reach the port can attempt to pair. Keep it on a private network (Tailscale) and scope the firewall rule; do not expose 7643 to the public internet. -
History is not pushed on
subscribe. Subscribe only acks; clients must sendget_historyexplicitly. -
The server pings. A client that never sends a pong frame will appear to hang with zero events.
gateway_client.pyanswers pings for you. -
jcode server reloadcan fail with "Client must Subscribe with a working_dir" on older builds. Fall back tostop --force+start.