The Headless Deskman
Public Unreviewedby barrett-land
A browser desktop for a headless Adom container. Runs Xvfb+fluxbox+x11vnc+noVNC inside the container and maps a *.adom.cloud port so any browser (or a Hydrogen webview tab) shows the container's GUI — no SSH tunnel, no local viewer. The container hosts the page itself. (Formerly Headview.)
name: headless-deskman description: "The Headless Deskman — turn a headless Adom container into a browser-accessible desktop. Use when a container has no display and you need to SEE a GUI app (KiCad, Fusion, a browser, any X11 program) running inside it, or when X11 forwarding over ssh -Y fails. Runs Xvfb+fluxbox+x11vnc+noVNC inside the container and maps a *.adom.cloud port so any browser (or a Hydrogen webview tab) shows the container's GUI. Trigger words: headless desktop, container desktop, headless deskman, deskman, headview (old name), view GUI from container, noVNC, run a GUI app in the container, remote desktop for container, browser desktop, X server in container, see kicad/gui in browser."
The Headless Deskman
headless-deskman gives a headless Adom container a real desktop you can open
in a browser. It starts a virtual X display in the container, scrapes it with VNC,
bridges that to WebSocket with noVNC, and maps a *.adom.cloud port so
Cloudflare serves the page — the container hosts it itself, no SSH tunnel and
no local VNC viewer. Open the URL anywhere, or drop it into a Hydrogen webview tab.
Renamed in 0.2.0: this was
headview. The command is nowheadless-deskman; the old binary is removed on install, and a desktop started under the old name is picked up automatically (state migrates from~/.config/headview).
Why not ssh -Y? X11 forwarding does not work through the adom.cloud SSH
gateway (the gateway relays the connection, so the X11 channel never reaches the
container). The Headless Deskman sidesteps that entirely by serving over
HTTP/WebSocket, which the gateway/Cloudflare pass fine.
Stack
Xvfb (:99) → fluxbox → x11vnc (localhost:5900) → noVNC/websockify (:6080) → port-mapping → https://<prefix>-*.adom.cloud/vnc.html
Rendering is software only (Xvfb has no GPU) — great for 2D GUIs, not for OpenGL/3D views.
Commands
headless-deskman up
Install deps if missing, start the desktop, map the port, print the URL + password. Idempotent — safe to re-run.
| Flag | Default | Description |
|---|---|---|
--display :N |
:99 |
X display number |
--geometry WxH |
1600x1000 |
screen size |
--vnc-port N |
5900 |
internal VNC port (loopback only) |
--web-port N |
6080 |
internal noVNC port that gets mapped |
--prefix NAME |
desktop |
subdomain prefix → NAME-<rand>.adom.cloud |
--app "CMD" |
— | launch CMD on the desktop after starting |
--no-password |
— | passwordless (only behind other access control) |
headless-deskman up # bare desktop
headless-deskman up --app "kicad" # desktop with KiCad already open
headless-deskman up --geometry 1920x1080
Set DESKMAN_PASSWORD to pin the VNC password instead of generating one.
headless-deskman open
Open the running desktop as a Hydrogen webview tab named "Container Desktop".
Must be run from a Hydrogen workspace terminal (needs VSCODE_PROXY_URI).
From anywhere else, use headless-deskman url and open it in a browser.
headless-deskman status / url / password
Inspect state: what's running, the URL, and the VNC password.
headless-deskman down
Stop Xvfb/fluxbox/x11vnc/noVNC and remove the port mapping. Add --keep-mapping to leave the mapping in place.
headless-deskman install
Install/refresh this skill from the wiki into ~/.claude/skills/headless-deskman/.
Launching apps onto the desktop
Anything you run with DISPLAY=:99 appears in the browser window:
DISPLAY=:99 pcbnew &
DISPLAY=:99 xterm &
Notes
- Run
headless-deskmaninside the target container — it auto-detects the container slug viaadom-cli carbon containers currentand maps its own port. - The VNC server binds
localhostonly; the public face is the noVNC HTTPS URL, protected by the generated VNC password (shown byup/password). - WebSocket idle: Cloudflare can drop very idle WS connections; noVNC reconnects, and any desktop activity keeps it warm.
---
name: headless-deskman
description: "The Headless Deskman — turn a headless Adom container into a browser-accessible desktop. Use when a container has no display and you need to SEE a GUI app (KiCad, Fusion, a browser, any X11 program) running inside it, or when X11 forwarding over ssh -Y fails. Runs Xvfb+fluxbox+x11vnc+noVNC inside the container and maps a *.adom.cloud port so any browser (or a Hydrogen webview tab) shows the container's GUI. Trigger words: headless desktop, container desktop, headless deskman, deskman, headview (old name), view GUI from container, noVNC, run a GUI app in the container, remote desktop for container, browser desktop, X server in container, see kicad/gui in browser."
---
# The Headless Deskman
`headless-deskman` gives a **headless** Adom container a real desktop you can open
in a browser. It starts a virtual X display in the container, scrapes it with VNC,
bridges that to WebSocket with noVNC, and maps a `*.adom.cloud` port so
**Cloudflare serves the page — the container hosts it itself**, no SSH tunnel and
no local VNC viewer. Open the URL anywhere, or drop it into a Hydrogen webview tab.
> Renamed in 0.2.0: this was `headview`. The command is now `headless-deskman`; the
> old binary is removed on install, and a desktop started under the old name is
> picked up automatically (state migrates from `~/.config/headview`).
Why not `ssh -Y`? X11 forwarding does **not** work through the `adom.cloud` SSH
gateway (the gateway relays the connection, so the X11 channel never reaches the
container). The Headless Deskman sidesteps that entirely by serving over
HTTP/WebSocket, which the gateway/Cloudflare pass fine.
## Stack
`Xvfb (:99)` → `fluxbox` → `x11vnc (localhost:5900)` → `noVNC/websockify (:6080)` → port-mapping → `https://<prefix>-*.adom.cloud/vnc.html`
Rendering is **software only** (Xvfb has no GPU) — great for 2D GUIs, not for
OpenGL/3D views.
## Commands
### `headless-deskman up`
Install deps if missing, start the desktop, map the port, print the URL + password. Idempotent — safe to re-run.
| Flag | Default | Description |
|------|---------|-------------|
| `--display :N` | `:99` | X display number |
| `--geometry WxH` | `1600x1000` | screen size |
| `--vnc-port N` | `5900` | internal VNC port (loopback only) |
| `--web-port N` | `6080` | internal noVNC port that gets mapped |
| `--prefix NAME` | `desktop` | subdomain prefix → `NAME-<rand>.adom.cloud` |
| `--app "CMD"` | — | launch CMD on the desktop after starting |
| `--no-password` | — | passwordless (only behind other access control) |
```bash
headless-deskman up # bare desktop
headless-deskman up --app "kicad" # desktop with KiCad already open
headless-deskman up --geometry 1920x1080
```
Set `DESKMAN_PASSWORD` to pin the VNC password instead of generating one.
### `headless-deskman open`
Open the running desktop as a Hydrogen webview tab named "Container Desktop".
Must be run from a **Hydrogen workspace terminal** (needs `VSCODE_PROXY_URI`).
From anywhere else, use `headless-deskman url` and open it in a browser.
### `headless-deskman status` / `url` / `password`
Inspect state: what's running, the URL, and the VNC password.
### `headless-deskman down`
Stop Xvfb/fluxbox/x11vnc/noVNC and **remove the port mapping**. Add `--keep-mapping` to leave the mapping in place.
### `headless-deskman install`
Install/refresh this skill from the wiki into `~/.claude/skills/headless-deskman/`.
## Launching apps onto the desktop
Anything you run with `DISPLAY=:99` appears in the browser window:
```bash
DISPLAY=:99 pcbnew &
DISPLAY=:99 xterm &
```
## Notes
- Run `headless-deskman` **inside the target container** — it auto-detects the
container slug via `adom-cli carbon containers current` and maps its own port.
- The VNC server binds `localhost` only; the public face is the noVNC HTTPS URL,
protected by the generated VNC password (shown by `up`/`password`).
- WebSocket idle: Cloudflare can drop very idle WS connections; noVNC reconnects,
and any desktop activity keeps it warm.