# Desktop

> A full Linux desktop, or a single Chrome window, from any box in your browser, streamed over VNC inside the private tunnel with nothing opened to the internet.

URL: https://prized.dev/docs/desktop

## Open [#open]

On the box page's **Desktop** tab, pick **Desktop** (XFCE) or **Browser** (one Chrome window), then click open. From the terminal:

```bash
prized desktop
prized browser --url https://example.com
```

It is up in a few seconds; a box created before September 2, 2026 installs the packages on its first open (about two minutes, once).

| Command                | What it does                                                                                                                                            |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prized desktop [BOX]` | Start the desktop, forward its VNC port to `127.0.0.1`, and open the dashboard tab. Runs until Ctrl-C; wakes a suspended box.                           |
| `prized browser [BOX]` | The same with one Chrome window. `--profile NAME` picks the [profile](#browser-profiles), `--url URL` the start page.                                   |
| `--no-open`            | Print the `vnc://127.0.0.1:PORT` address and the password for a native VNC client instead of opening the dashboard.                                     |
| `--stop`               | Stop the desktop (or browser) on the box and exit. Never wakes a paused box.                                                                            |
| `--json`               | Print `{"ok":true,"box":"…","mode":"desktop","localPort":…,"password":"…","dashboardUrl":"…"}` once the forward listens, open nothing, keep forwarding. |

## What you get [#what-you-get]

* **Desktop:** XFCE with a terminal, a file manager and Chrome; `xdotool` and `wmctrl` are installed for scripts.
* **Browser:** one maximized Chrome window and nothing else; sign in to a site once and tools on the box can reuse the profile.
* **Keyboard and mouse** work as in a native window; the tab's header has full screen and two clipboard buttons, paste to the box and copy from it.
* **Closing the tab leaves the desktop running**, with the same windows when you reopen it; **Stop desktop** in the tab, or `prized desktop --stop`, ends it.

## Let an agent drive it [#let-an-agent-drive-it]

An agent on the box can use a web page or any GUI app on its own, from its shell; nothing needs to run on your machine. The tools below come with the box image; on a box created before September 2, 2026 whose desktop was never opened, and for `scrot` on older images, install them first:

```bash
sudo apt-get update && sudo apt-get install -y xvfb openbox xdotool wmctrl scrot
```

If `google-chrome-stable` is missing too, install it with `curl -fsSL -o /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && sudo apt-get install -y /tmp/chrome.deb`.

**Web pages:** headless Chrome needs no screen and is the most reliable.

```bash
google-chrome-stable --headless=new --user-data-dir=/tmp/agent-headless --window-size=1280,800 --screenshot=/tmp/page.png https://example.com
```

For clicks and forms, Playwright works from Python, which the box has (Node is not preinstalled): `python3 -m venv ~/pw && ~/pw/bin/pip install playwright`, then launch the installed Chrome with `channel="chrome"`.

**Any GUI app:** start a screen of its own, with a window manager so `wmctrl` sees the windows, then run the app on it.

```bash
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp & sleep 1; DISPLAY=:99 openbox &
```

| Task                | Command                                                                                    |
| ------------------- | ------------------------------------------------------------------------------------------ |
| Run an app          | `DISPLAY=:99 google-chrome-stable --user-data-dir=/tmp/agent-chrome https://example.com &` |
| Screenshot          | `DISPLAY=:99 scrot -o /tmp/screen.png`, then read the PNG                                  |
| Click               | `DISPLAY=:99 xdotool mousemove 960 540 click 1` (`click 3` for the right button)           |
| Type and press keys | `DISPLAY=:99 xdotool type 'hello'`, `DISPLAY=:99 xdotool key ctrl+l Return`                |
| Windows             | `DISPLAY=:99 wmctrl -l`, `DISPLAY=:99 wmctrl -a 'Google Chrome'`                           |

To watch the agent work, open the desktop (`prized desktop` or the **Desktop** tab) and have it use `DISPLAY=:10`, without starting a screen of its own.

Give your agent this prompt:

```text title="Prompt"
This Linux box has no screen attached. If a command below is missing, run `sudo apt-get update && sudo apt-get install -y xvfb openbox xdotool wmctrl scrot` first. For a web page, prefer headless Chrome: google-chrome-stable --headless=new --user-data-dir=/tmp/agent-headless --window-size=1280,800 --screenshot=/tmp/page.png URL, then read the PNG. For an interactive browser or any other GUI app, start a virtual screen once with `Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp & sleep 1; DISPLAY=:99 openbox &`, run the app with DISPLAY=:99, and work in a loop: take a screenshot with `DISPLAY=:99 scrot -o /tmp/screen.png` and read the PNG, then act with xdotool (`mousemove X Y click 1`, `type 'TEXT'`, `key ctrl+l`) and wmctrl (`-l`, `-a NAME`), all with DISPLAY=:99. Take a new screenshot after each step to check it worked.
```

## Browser profiles [#browser-profiles]

A profile is Chrome's user data directory at `~/.prized/browser/<name>` on the box (`default` when you name none): sign-ins, cookies and extensions persist across restarts and ride a [snapshot](https://prized.dev/docs/boxes#snapshots). Names use letters, digits, `-` and `_`, up to 64 characters.

Starting the browser with a different profile replaces the running window; starting it again with the same profile and a URL opens that page as a new tab.

## Pause and resume [#pause-and-resume]

On Nano through Small the desktop resumes as it was; Medium and larger start a fresh one, and files, packages and profiles survive either way ([Pause and resume](https://prized.dev/docs/boxes#pause-and-resume)).

> A running desktop may count as activity for [auto-pause](https://prized.dev/docs/boxes#auto-pause) even with nobody connected; if you rely on auto-pause, stop the desktop when you are done.

## Security [#security]

* **Loopback only.** The VNC server listens on the box's loopback; nothing new is reachable from the internet.
* **A random password per start**, kept only on the box in a file only your user can read. The dashboard uses it for you; `--no-open` and `--json` print it, and the default output shows only the forwarded `vnc://` address.
* **The VNC port** (5910 for the desktop, 5911 for the browser) appears in `prized ports` like any listener, but needs no mirroring: the desktop command forwards it itself.

## Limits [#limits]

* VNC, not video: responsive for editors, terminals and browsing, not full-motion video. No audio.
* Fixed 1920x1080, scaled to your window. No GPU on any box size.
* Agents and scripts drive the desktop, or a screen of their own, from a shell ([Let an agent drive it](#let-an-agent-drive-it)): `DISPLAY=:10` is the desktop, `DISPLAY=:11` the browser window.
* One desktop and one browser window per box.

## Troubleshooting [#troubleshooting]

| Symptom                                      | What to do                                                                                                         |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `desktop install failed`                     | On the box, `cat ~/.prized/desktop/install.log` names the cause (network, or a held apt lock); open the tab again. |
| A black screen after connecting              | The session is still starting; if it stays black, **Stop desktop** and open again.                                 |
| `the box refused the VNC password`           | A stale password after a restart; open the tab again.                                                              |
| No Chrome window in browser mode             | `cat ~/.prized/desktop/browser-session.log` on the box; a profile in use by another Chrome blocks a second one.    |
| Shortcuts go to your own browser             | Use full screen; Cmd/Ctrl+W, Cmd/Ctrl+T and the like always stay with your browser.                                |
| `prized desktop` says the box is unreachable | Same tunnel as `prized ssh`: run `prized doctor`.                                                                  |
