#!/bin/bash # Sets up a Linux desktop you use from your browser, on an exe.dev VM (Ubuntu 24.04): # Xfce on KasmVNC (display :1), its web client on port 8444, behind exe.dev login: # https://.exe.xyz:8444/ # Google Chrome as the default browser, and launchers for the coding agents # the VM comes with (Claude Code, Codex, OpenCode, Pi), set up to use exe.dev's # LLM integration. # Run it as the VM's user (exedev); it uses sudo. Safe to run again. # From https://exe.dev/deploy/linux-desktop set -euo pipefail KASMVNC_VERSION=${KASMVNC_VERSION:-1.5.2} PORT=${PORT:-8444} U=$(id -un) H=$HOME ARCH=$(dpkg --print-architecture) echo "== packages" sudo apt-get update -q sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends \ xfce4 xfce4-terminal xfce4-taskmanager mousepad ristretto dbus-x11 xdg-utils \ fonts-noto fonts-noto-color-emoji fonts-noto-cjk if [ "$(dpkg-query -W -f='${Version}' kasmvncserver 2>/dev/null)" != "$KASMVNC_VERSION" ]; then curl -fsSL -o /tmp/kasmvnc.deb \ "https://github.com/kasmtech/KasmVNC/releases/download/v$KASMVNC_VERSION/kasmvncserver_ubuntu_noble_${KASMVNC_VERSION}_$ARCH.deb" sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q /tmp/kasmvnc.deb rm -f /tmp/kasmvnc.deb fi if ! command -v google-chrome >/dev/null; then curl -fsSL -o /tmp/google-chrome.deb \ https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q /tmp/google-chrome.deb rm -f /tmp/google-chrome.deb fi echo "== desktop" # KasmVNC reads the snakeoil certificate even when it serves plain HTTP. sudo adduser -q "$U" ssl-cert # It also wants a user of its own; we turn its password check off below, since # exe.dev's login guards the desktop, so this password is random and unused. if [ ! -s "$H/.kasmpasswd" ]; then P=$(openssl rand -hex 16) printf '%s\n%s\n' "$P" "$P" | kasmvncpasswd -u "$U" -w >/dev/null fi mkdir -p "$H/code" "$H/.vnc" "$H/Desktop" "$H/.local/share/applications" "$H/.config/xfce4" # KasmVNC: plain HTTP on $PORT (exe.dev's proxy adds HTTPS and the login), # no password of its own, resized to fit the browser window. cat > "$H/.vnc/kasmvnc.yaml" < "$H/.vnc/xstartup" <<'SH' #!/bin/sh unset SESSION_MANAGER DBUS_SESSION_BUS_ADDRESS exec dbus-launch --exit-with-session startxfce4 SH chmod +x "$H/.vnc/xstartup" touch "$H/.vnc/.de-was-selected" # Chrome is the browser the panel and links open. printf 'WebBrowser=google-chrome\nTerminalEmulator=xfce4-terminal\n' > "$H/.config/xfce4/helpers.rc" # A launcher per coding agent, in the menu (Development) and on the desktop. launcher() { # file name command comment cat > "$H/.local/share/applications/$1.desktop" </dev/null <