Development
rd is a Rust workspace (the agent, the gateway, the protocol and flow control), a TypeScript viewer built with Vite and Bun, and a Tauri app. This page is the map; each part’s own notes are linked from it.
Repository layout
Section titled “Repository layout”Directorycrates/
Directoryrd-proto/ wire protocol shared by agent and gateway, HID keymap, golden test vectors
- …
Directoryrd-flow/ flow control: in-flight window and delay-based bitrate controller
- …
Directoryrd-agent-core/ agent runtime, selftest harness, test pattern (platform independent)
- …
Directoryrd-platform-macos/ ScreenCaptureKit, VideoToolbox, CGEvent, IOKit, Keychain
- …
Directoryrd-platform-windows/ Desktop Duplication (GDI when there is no display driver), D3D11 video processor, Media Foundation, SendInput
- …
Directoryrd-agent/ the agent binary (run, setup, install, uninstall, status, update, selftest) and rd-agentw, the Windows background launcher
- …
Directoryrd-gateway/ relay, portal, network probe; embeds viewer/dist
- …
Directoryviewer/ TypeScript viewer (Vite + Bun)
- …
Directoryclients/
Directorydesktop/ rd Desktop (Tauri), with its own Cargo.lock
- …
Directorytools/
Directorygen-keymap/ Chromium key table → Rust and TypeScript keymaps
- …
Directoryrelease/ changesets helpers: versions, update manifests
- …
Directorypackaging/
Directorymacos/ app bundle, signing, LaunchAgent
- …
Directorywindows/ the agent’s per-user NSIS installer
- …
Directoryhome/guacd/ the recovery path’s guacd at home
- …
- deploy/Dockerfile gateway image (linux/arm64)
Directorytests/desktop-e2e/ rd Desktop keyboard grab, end to end on a Windows runner
- …
Directorysite/ this documentation site
- …
Directorydocs/ the guides this site publishes
- …
Checks
Section titled “Checks”Before you push, run the checks CI runs (.github/workflows/ci.yml), plus the key table
check, which CI leaves to you:
cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace(cd viewer && bun install --frozen-lockfile && bun run typecheck && bun run test && bun run build)bun tools/release/sync-versions.ts --check && bun test tools/releasebun tools/gen-keymap/gen.ts --checkCI (.github/workflows/ci.yml) runs the platform-independent crates, the agent (Linux has no
platform crate: it serves the terminal and files) and the viewer on Linux, and the agent with its
platform crate on macOS and on Windows. rd Desktop is built and tested by
desktop.yml, the agent’s installers by agent.yml, and the gateway image by
gateway-image.yml.
Local loops
Section titled “Local loops”- Everything on one machine: the quick start.
--devturns off authentication and keeps devices added in the portal in memory (unless--state-diris given). - Viewer:
bun run devinviewer/serves it on port 5173 with hot reload, and proxies/apiand/wsto a gateway on127.0.0.1:8080. Or rebuild it (bun run build, orbunx vite build --watch) and let the gateway serveviewer/distwith--assets-dir. - Bad networks:
RD_CHAOS=bw_kbps=5000,delay_ms=50(development mode only) puts a bottleneck between the agent and the viewer. It never drops or reorders messages, and backpressure still reaches the agent. - Agent without a screen:
--source syntheticstreams a test pattern through the real encoder;rd-agent selftestcaptures and encodes for ten seconds and reports frame rate, encode latency and the stream’s parameters (--synthetic,--record out.rdv). - Windows platform code:
cargo run -p rd-platform-windows --example probelists monitors, GPUs and the H.264 encoders Media Foundation offers. More in Windows agent → Local development. - rd Desktop: Local testing, including an update end to end with a throwaway key.
Tests worth knowing
Section titled “Tests worth knowing”- Golden vectors:
crates/rd-proto/testvectors/binary.jsonholds encoded messages that both the Rust codec and the viewer’s TypeScript codec must read and write identically. - Gateway:
cargo test -p rd-gatewaystarts the gateway in-process on loopback ports with short timers and drives it over real WebSockets: auth, sessions, the probe, HTTP, devices, updates and backpressure. - Flow control:
crates/rd-flow/tests/sim.rsruns the window and the bitrate controller against simulated links; the thresholds were tuned there. - Keyboard grab:
tests/desktop-e2eruns the debug rd Desktop, a dev gateway and a fake agent on a GitHub-hosted Windows runner, types withSendInput, and checks which keys reach the “remote” machine. - Key tables:
bun tools/gen-keymap/gen.tsregenerates them from Chromium’s DOM code table;--checkfails when they are out of date.
Releases
Section titled “Releases”rd Desktop and the rd agent are released separately with changesets. Every pull request should include one:
bun install && bun changeset # pick rd-desktop and/or rd-agent, then patch / minor / majorbun changeset --empty # a change only to the gateway, the viewer or the docsWrite the text for the people who use rd: it is what they read in the update window (rd Desktop)
or under What’s new in the portal (agent). Merging to main opens or updates a Version
packages pull request; merging that one tags desktop-vX.Y.Z and/or agent-vX.Y.Z, and the
release workflows build, sign and publish them, after which installed copies offer the update.
The gateway image is versioned on its own (gateway-vX.Y.Z, on every push to main that touches
it). Details: Updates and rd Desktop → Releasing.
This site
Section titled “This site”The site lives in site/ and is built with Astro Starlight
(Astro 7 needs Node 22.22 or later). Most guides are synced, not copied by hand: each build
reads the Markdown files in docs/, clients/desktop/README.md and viewer/README.md (listed
in site/integrations/pages.mjs) and turns their relative links into links between pages. So
edit those files, not the copies, and the site follows.
cd sitebun installbun run dev # http://localhost:4321/remoted/bun run build # → site/distThe Pages workflow (.github/workflows/pages.yml) builds the site for every pull request
that touches it or the synced files, and publishes it to GitHub Pages from main.