tools/remote-desktop-testing-linux/SKILL.md
Test any GUI app or change on a Daytona Linux (Ubuntu xfce4 + noVNC) remote desktop sandbox. Use to launch a GUI program, sync a local project, take a screenshot, record a video, or share a clickable live-desktop link with a teammate. Generic — the only dependency is Daytona. For Windows, use remote-desktop-testing-windows.
npx skillsauth add letta-ai/skills remote-desktop-testing-linuxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generic Daytona Linux desktop sandbox driver. It creates (or reuses) a sandbox running an xfce4 desktop streamed over noVNC, and provides the primitives for visual testing of any GUI app: sync code, run shell commands, launch GUI programs on the live desktop, screenshot, record video, and mint a clickable desktop link a teammate can open to drive the app.
cleanup)Run the bundled script with Node from the skill directory:
node scripts/remote-desktop.mjs <command> [options]
Credentials: DAYTONA_API_KEY (and optionally DAYTONA_API_URL/DAYTONA_TARGET) from the
environment or a dotenv file — ./.env by default, override with --env-path <file>.
The script auto-installs @daytona/sdk under ~/.letta/skill-state/remote-desktop-testing-linux/
on first use and remembers the active sandbox id there, so later commands don't need --sandbox.
# 1. Start (or reuse) a desktop sandbox. Default: image daytonaio/sandbox:0.8.0, cpu 2 / mem 4 / disk 5.
node scripts/remote-desktop.mjs start
# 2. (Optional) push a local project to /home/daytona/remote-desktop/workspace
node scripts/remote-desktop.mjs sync --project-path ~/repos/my-app --sync-mode working_tree
# 3. Set up / build with shell commands (runs bash in the sandbox)
node scripts/remote-desktop.mjs shell \
--command "cd /home/daytona/remote-desktop/workspace && npm install"
# 4. Launch the GUI app on the live desktop and verify its window appeared
node scripts/remote-desktop.mjs launch \
--command "./my-app --some-flag" --label my-app --wait-window "My App"
# 5. Deliverables: screenshot, video, and a clickable live-desktop link
node scripts/remote-desktop.mjs screenshot --output /tmp/demo.png
node scripts/remote-desktop.mjs record --output /tmp/demo.mp4 --mp4 --duration 12
node scripts/remote-desktop.mjs preview
Always confirm the result visually (open the screenshot, or check windows / --wait-window)
before reporting success — never report success from process existence alone. When sharing with
a teammate, send the desktopUrl from preview (signed noVNC link, expires ~6h; re-run
preview to refresh). Pass --port <n> to preview to also mint a signed URL for an app's
HTTP port.
| Command | What it does |
| --- | --- |
| start | Create/reuse a sandbox and start the desktop. --fresh forces a new one. |
| sync | Sync --project-path to /home/daytona/remote-desktop/workspace (git_archive = committed HEAD, working_tree = uncommitted too; preserves remote node_modules). |
| shell --command SH | Run a bash command. --timeout <s> for long ones. |
| launch --command CMD | Launch a GUI command on the xfce4 desktop (detached, DISPLAY set, logged to /home/daytona/remote-desktop/launch-<label>.log). --wait-window <regex> verifies a matching window title appears. |
| windows | List visible desktop windows. |
| screenshot | Save a PNG of the full desktop locally. |
| preview | Print signed desktopUrl (noVNC), plus appUrl if --port given. |
| record | Record the live desktop via Playwright + local Chrome (--duration <s>, --mp4). |
| recording-start/stop/download | Native Daytona recording (installs ffmpeg in-sandbox on first use). |
| snapshot --snapshot <name> | Bake the sandbox into a snapshot (stops, snapshots, restarts). |
| cleanup | Stop the active sandbox. |
daytonaio/sandbox:0.8.0 with --cpu 2 --memory 4 --disk 5
by default; raise them for big projects (--cpu 4 --memory 8 --disk 10). Disk is capped at
10GB per sandbox.resources cannot be combined with a snapshot — --snapshot <name> creates with whatever
size was baked in. Use snapshot to bake a prepared box (deps installed, caches warm) so
future start --snapshot <name> runs skip setup. Revert throwaway edits before baking.--no-sandbox inside the container, and often
--disable-gpu --disable-dev-shm-usage too; put those flags in your launch --command.launch runs the command detached with DISPLAY pointed at the live desktop (detected from
/tmp/.X11-unix, falls back to :0). Check the launch log via shell if nothing appears.desktopUrl (the interactive desktop), not a raw app-port URL —
the app URL only serves HTTP and shows nothing of the desktop.record runs Playwright locally: it resolves playwright/playwright-core from
--project-path first, else auto-installs playwright-core into skill state, and drives the
local Chrome binary (--chrome-path, default macOS Chrome). --mp4 needs local ffmpeg.xfce4-terminal, chromium, and xeyes available for quick desktop
sanity checks (e.g. launch --command "xfce4-terminal" --wait-window Terminal).tools
Test any GUI app or change on a Daytona Windows remote desktop sandbox. Use to launch a GUI program, sync a local project, take a screenshot, record a video, or share a clickable live-desktop link with a teammate. Generic — the only dependency is Daytona. For Linux, use remote-desktop-testing-linux.
testing
Configures Letta agents' own runtime behavior, including model, context window, system prompt, reasoning, conversation overrides, compaction settings, and compaction prompts. Use when an agent or user asks to self-modify, tune summarization/compaction, change identity/system instructions, adjust model settings, or test conversation-scoped overrides.
development
Sets Letta Desktop and Letta Code agent profile images by writing profile.png into an agent MemFS repository. Use when the user asks to add, change, generate, or fix an agent avatar, profile picture, profile image, or Desktop agent photo.
testing
Navigates archived ChatGPT or Claude-style conversation exports and a MemFS reference archive on demand. Use when recalling what a past assistant knew, searching old conversations, rendering specific chats, seeding reference memory from export sidecars, or mining historical context without doing a full import.