tun-poc-server

moon add tonyfettes/tun-poc-server@0.3.3
Download zip
Version
0.3.3
License
Apache-2.0
Last updated
16 days ago
Downloads
93
README

#tun-poc-server

The server agent for tun-poc. Runs on the machine you want to expose, opens one PTY-backed task, and maintains an outbound WebSocket to a relay. Multiple clients attached to the task share that PTY.

No inbound ports are required — it works behind home routers, corporate firewalls, and carrier-grade NATs.

Responsibilities:

  • Generate one task_uuid per process invocation and reuse it across relay reconnects.
  • Spawn one PTY through moonbit-community/pty and stream its I/O to the local terminal and attached remote clients.
  • Keep the PTY and local shell alive across relay disconnects, then re-register the same task when the relay returns.
  • Resolve XDG paths for scoped credential storage (xdg/).

#Run

# connect to the hosted relay moon run server --target native # connect to the China-hosted relay moon run server-cn --target native # expose a specific program instead of the default shell moon run server --target native -- /bin/bash moon run server --target native -- -- htop # point at a self-hosted relay moon run server --target native -- --relay your.relay.example.com

The agent logs its task_uuid — keep the process running for that task to stay reachable. Restarting the process creates a new task UUID.

#Build And Publish Artifacts

Server release binaries are built from the repo root:

make build-server make build-server-linux

The outputs are written under downloads/ as tun-server-<platform> files with .sha256 sidecars. The current manual publishing workflow bundles those files into the relay image. See ../docs/publishing.md for the current steps and ../docs/plans/2026-04-27-structured-publishing-workflow.md for the plan to publish server binaries independently.

The server keeps a PTY replay tail in memory for reconnect catch-up. The default is 4 MiB, and it can be configured in tun-poc/config.json under the per-user config directory:

  • macOS: ~/Library/Application Support/tun-poc/config.json
  • Linux: ${XDG_CONFIG_HOME:-~/.config}/tun-poc/config.json
  • Windows: %LOCALAPPDATA%/tun-poc/config.json

{ "history_size": "4MiB", "renderer": "ghostty" }

history_size accepts strings with B, KiB, or MiB, and bare JSON numbers are interpreted as bytes. renderer accepts tee or ghostty; --render and TUN_POC_RENDERER override the config file. Replay is a bounded byte suffix, not a terminal snapshot: once the tail trims, a fresh client or a client reconnecting with an older cursor can receive output from the middle of the PTY stream and cannot rely on replay alone to reconstruct the full screen state.

#Terminal backend

The PTY is created at the portable 80x24 fallback (see server/internal/app/bridge.mbt). In ghostty mode bridge startup reads the foreground terminal's physical grid and applies that initial size before PTY reader tasks start. The foreground terminal is rendered by server/terminal/, a concrete package backed by the published tonyfettes/ghostty/terminal dependency. The default tee mode writes PTY output directly to stdout and preserves stdin bytes exactly.

In ghostty mode, server/terminal enters the launching host terminal's alternate screen, enables SGR mouse reporting, feeds PTY output through Ghostty, and repaints the negotiated viewport itself. Render-capable remote clients report visible sizes; the PTY uses the component-wise minimum across the local physical viewport and active render-client viewports. A legacy client retains its 80x24 remote contract, bounded by a smaller local viewport. With no active participant the fallback remains 80x24. The host primary-screen scrollback is not used for the local UI; mouse wheel events adjust server-owned scrollback. host_teardown disables mouse reporting and leaves the host alternate screen before termios is restored. Ghostty input and native resize notifications come from moonbit-community/tty's coordinated event reader. The same TTY handle queries OSC 10/11/12 host colors before that reader starts, so color replies cannot race with child input.

The rest of server/ talks only to the small @terminal facade, including new, pty_to_host, host_event_to_pty, host_to_pty for tee bytes, host_setup, and host_teardown. PTY query replies generated by Ghostty flow back through pty_reader, which writes them to the PTY master.

Source Files