Desktop
Every VM has a Linux desktop (XFCE, 1920x1080, with Chrome) that you can watch and use in your browser, for example to see what an agent is doing. Click Desktop next to a running VM in the dashboard, or:
$ froog desktop my-box # opens it in your browser
$ froog desktop my-box --theme light # dark (default) or light
$ froog desktop my-box --print # just print the link
The link opens froog's viewer. Its ☰ button has fullscreen, reconnect, the connection (below), scaling and picture quality (VNC only), Ctrl+Alt+Del and other keys, a clipboard box (text copied in the sandbox shows up there, and text you put there can be sent in) and a view-only switch. A line at the bottom left shows the resolution, frame rate (or data rate), connection and session time. The desktop starts the first time you open it and keeps running until the VM stops.
Fast stream, with VNC as the fallback. The viewer shows the desktop as H.264 video at up to 60 frames a second, encoded on the sandbox's CPU by Selkies and sent over the same HTTPS address as the page. If the stream isn't there or shows nothing within a few seconds, the viewer uses VNC instead, as before. The stream runs on Ubuntu and Debian sandboxes. The first open installs it (about 20 seconds more, once). Omarchy uses VNC. Several pages can show one desktop at once (it is encoded once for all of them). View-only pages, like the wall's tiles or an embed with viewonly=1, join as watchers that can't send input. Pick Compatible (VNC) under ☰ → Connection to stay on VNC (the viewer remembers it), or add transport=vnc to the link's query for one page.
What it costs, measured on a default sandbox (4 vCPUs on an Intel i7-6700 host) with one viewer at 1920x1080, the stream uses about 0.2 vCPU on a still screen (plus about 0.15 in the X server handing it frames) and sends nothing (only changed frames go out), about 0.4 vCPU while a terminal scrolls as fast as it can, and about 1 vCPU for full-screen motion at 60 frames a second and 6 Mbit/s. A small sandbox (2 vCPUs) also kept 60 frames a second of full-screen motion, at about 0.8 vCPU. VNC sent about 160 Mbit/s for the same motion. Nothing is encoded while no one watches.
Sound. What the desktop plays comes through the fast stream, as Opus at 128 kbit/s. The desktop has a sound server of its own (PulseAudio, with one virtual speaker that every program plays to), so no sound card is needed. Browsers start playing it after your first click in the page. Turn it off with Sound under ☰ (the viewer remembers it), or add sound=0 to the link's query for one page. Off also stops the sandbox capturing and encoding it, and can turn it off for other pages open on the same desktop. View-only pages have no switch. VNC, the browser view and Omarchy have no sound. The cost: about 0.1 vCPU while a viewer is connected with sound on and something plays, for the sound server and the Opus encoder (measured on a small sandbox, Intel i7-6700 host: 0.18 vCPU for the stream with sound off, 0.26 to 0.29 with it on). With no viewer the sound server alone uses about 0.03 vCPU while something plays. Desktops started before this release get sound when the sandbox restarts.
Links. A link carries a secret token after the # (browsers never send that part to a server, and the viewer takes it out of the address bar at once). Open it within 10 minutes. A session you have open keeps working after that. Reconnecting within the 10 minutes works. After that, or after a stop, ask for a new link. Treat links as secrets and don't log them. A link opens only its own view: a desktop link can't open the browser view, nor the other way round.
Embed it. From your server, call POST /v1/sandboxes/{name}/desktop (it returns {url, expires_at}) on each page load, add overlay=0 to the query (before the #) to hide the controls and stats, and put it in an iframe:
<iframe src="DESKTOP_URL" allow="autoplay; fullscreen; clipboard-read; clipboard-write" style="width:100%;aspect-ratio:16/9;border:0"></iframe>
Your own background. Put a PNG at ~/.config/froog/wallpaper.png on the sandbox, and the desktop shows it within two seconds, filling the screen and keeping its aspect ratio. Up to 16 MiB, 8192 pixels a side and 16,777,216 pixels in all. A file that isn't a valid PNG is ignored. Delete it to go back to the plain background. It's on the disk, so it stays through stops, snapshots and forks: froog scp ./wallpaper.png my-box:.config/froog/wallpaper.png.
Browser only. To show someone Chrome and nothing else, open the browser view: only Chrome, on its own 1920x1080 screen with no desktop behind it, with its tabs and address bar but no window controls. Closing the last tab opens a new window, so the view never ends on a blank screen. It runs next to the desktop (a separate screen and a separate Chrome) and has no clipboard.
$ froog browser my-box # profile ~/.config/froog-browser
$ froog browser my-box --profile /data/chrome-work # another signed-in profile
A profile is Chrome's user data directory: any absolute path outside the system directories, created if missing, kept on the disk (so it goes with snapshots and forks). Asking for another profile closes the open one. API: POST /v1/sandboxes/{name}/browser with {"profile": "/data/chrome-work"} (optional). The browser view isn't a security boundary against code running in the sandbox, which can read Chrome's profile.
Record it. froog-record-desktop records the desktop to an MP4 (H.264, 30 fps, with the desktop's sound as AAC) from inside the sandbox:
$ froog exec my-box -- froog-record-desktop start /home/user/demo.mp4
# … drive the desktop, or let an agent do it …
$ froog exec my-box -- froog-record-desktop stop # finishes the file
$ froog scp my-box:demo.mp4 .
froog-record-desktop status says whether it's recording. Stop before you download: the file isn't playable until then. froog desktop my-box --tunnel reaches the desktop through an SSH tunnel to localhost instead of a link.