Download

name: hd-ui description: > HD's user interface: menus, dialogs, panels, login/logout, profile menu, workspace layout, setup panel — and how to DRIVE them from the workspace via the UI command bus (GET /ui/actions → POST /ui/invoke), the first-class way to open/close/toggle any HD menu or dialog (no CDP clicking). READ when the user asks you to open/close a dialog or menu, operate HD's UI, or you need to know where a UI element is. Trigger words — HD menu, HD dialog, HD panel, open dialog, open menu, close dialog, drive UI, ui/actions, ui/invoke, command bus, ports.open, settings.open, about dialog, profile menu, login, logout, settings, setup panel, Adom menu, HD UI.

Hydrogen Desktop — UI Reference

Window Layout

HD's window has these regions (top to bottom, left to right):

Title Bar

  • Left: "jlauer12 / Hydrogen Desktop" — shows user + app name
  • Right: CPU/RAM badges, window controls (minimize/maximize/close)

Tab Bar

  • VS Code tab — the main code editor (iframe to code-server)
  • Webview tab — wiki/app content panel
  • Additional tabs for bridges, sensors, etc.

Main Content Area

  • Left pane: Usually VS Code iframe
  • Right pane: Usually webview (wiki, shotlog, etc.)
  • Panes are split and resizable

Setup Panel (bottom)

  • Collapsible panel showing the setup-cascade steps (27 steps under the WSL2 runtime)
  • See hd-setup skill for details

Adom Menu (top-left logo dropdown)

The main menu, opened by clicking the Adom logo at the top-left. Items are grouped into labelled sections (in order, top to bottom):

(top, unlabelled)

  • Go to Dashboard — switches to the Hydrogen dashboard view
  • Settings — opens the Settings dialog
  • Ports... — opens the port configuration dialog (see hd-ports)
  • API Explorer... — opens the control-API endpoint explorer dialog

DESKTOP (Tauri-only — won't appear in browser-served HD; in order)

  • Adom Desktop — brings the embedded Adom Desktop window to the foreground (taskbar); bus id adom-desktop.open
  • Zoom — webview zoom controls (− % +) with persistence across launches
  • Fullscreen — toggle fullscreen
  • Console — show/hide the HD debug console window
  • Developer Tools — open WebView2 DevTools
  • Dev Toolbar — show/hide the Adom Dev Toolbar window (eval-in / shot / Claude control endpoints); bus id dev-toolbar.toggle

The Bridges section / "Bridge Manager" item was removed (it was a no-op with no backing panel). For the bridge panel itself, see hd-bridges.

Workspace / runtime section (section label shows live status badge: RUNNING, STOPPED, etc.)

  • Restart — restarts the workspace; under WSL2 this terminates the Adom-Workspace distro and re-ensures code-server, under the Docker runtime it's docker restart <container>.
  • Stop — stops the workspace; under WSL2 this terminates the Adom-Workspace distro, under the Docker runtime it's docker stop <container>.

ADMIN

  • Setup Steps — opens the setup panel (the setup cascade for the active runtime; 27 steps under WSL2); see hd-setup-steps
  • Virgin Reset — opens the virgin reset section of the setup panel; see hd-volume for what each toggle deletes
  • Browser Picker Manager — configure per-domain default browser/profile prefs; see hd-browser-picker

Profile Menu (top-right avatar)

Click the user avatar (circular photo) in the top-right corner.

  • Your profile — view Adom profile
  • Your repositories — list repos
  • Your molecules — list molecules
  • Log out — signs out of Adom, removes session token

CRITICAL: Logout is ONLY in the profile menu (top-right avatar), NOT in the Adom menu (top-left). Future AI threads: don't look for logout in the wrong menu.

Dialogs

Port Settings Dialog

Access: Adom menu → Ports... Shows all configurable ports with live conflict detection. Fields: Code Editor, Workspace Proxy, Control API, DevTools (CDP), Hostname. See hd-networking skill for port details.

Settings Dialog

Access: Adom menu → Settings Application-level preferences.

Browser Picker Dialog

Appears when clicking external links. Shows detected browser profiles (Edge, Chrome, etc.) with per-domain "remember" option.

Driving the UI — the command bus (PREFERRED, first-class)

Every menu / dialog / panel HD has wired is a first-class action you drive over the control API — no CDP, no .click(), no selector guessing. This is how you operate HD's UI when the user says "open the Ports dialog", "open About", "show settings", etc.

Get the control URL from the discovery file ~/.adom/hd-control-url (HD rewrites it with the live, dynamic control port every launch; it's the host loopback, shared with the distro by WSL2 mirrored networking). Read it from a file, not an env var — your Bash tool runs non-interactive shells that don't source .bashrc/profile.d:

CTRL="$(cat ~/.adom/hd-control-url)"

Always do this in order:

  1. Discover what's drivable (ids + descriptions):
    curl -s "$CTRL/ui/actions"
    # → {ok, count, actions:[{id,label,description,group}], _hints}
    
  2. Drive one — returns ONLY after the frontend actually ran it:
    curl -s -X POST "$CTRL/ui/invoke" \
      -H 'Content-Type: application/json' -d '{"id":"ports.open"}'
    # → {ok:true, id:"ports.open", value:…}
    
  3. Not in the list? That absence is the signal: the element isn't wired to the bus yet. It needs a 2-line registerUiAction(...) in its Svelte component (a dev change in the hydrogen-desktop repo — see that repo's hd-ui-actions skill). Don't fall back to clicking; wire it. The response's _hints.if_missing says the same.

Common ids (always GET /ui/actions for the live set): adom-menu.open/.close, profile-menu.open/.close, ports.open/.close, settings.open/.close, api-explorer.open/.close, browser-picker.open/.close, about.open/.close, adom-desktop.open, setup-panel.show, virgin-reset.open, dashboard.go, fullscreen.toggle, console.toggle, devtools.open, dev-toolbar.toggle, container.start/.stop/.restart.

Menu ITEMS, not just open/close: the profile menu also exposes per-item actions — profile.view, profile.repositories, profile.molecules, profile.logout — so you can trigger a specific item directly (it navigates as if the human clicked it), WITHOUT opening the menu + screen-clicking. (profile.logout is the canonical logout — see the logout note above.) GET /ui/actions for the live set; the Adom menu will get the same item-level treatment over time.

Note: there is no port-mappings.open/.close id — that action was never registered. Don't try to invoke it. Gap: setup-panel has .show but no .hide — to close it, eval window.__hdSetSetupPanel(false) (via /eval-in) or open another surface. A setup-panel.hide action is on the wishlist.

Open a surface, then screenshot it (the killer combo)

Combine the bus with HD's canonical capture endpoint to grab any menu/dialog/panel with no screen-clicking: POST /ui/invoke {id:"<x>.open"}POST /screenshot {target:"shell", selector:"<open-state selector>"}POST /ui/invoke {id:"<x>.close"}. The /screenshot region-flash lands on that selector. Resolved selectors (verified live): Adom & profile menus.dropdown-content.open (one open at a time); Setup panel.setup-panel; API Explorer.dialog. Full /screenshot reference (target/selector/ b64/silent) is in hd-self-screenshot.

This is HD-desktop-only and SEPARATE from adom-cli. adom-cli drives web-hydrogen's UI via the SSE bridge (ADOM_HYDROGEN_URL) and is unchanged. For HD desktop's far richer UI control, use the command bus above — never adom-cli for this.

Legacy: raw CDP clicking (deprecated fallback — the command bus above is canonical)

⚠ The command bus (/ui/actions/ui/invoke) is the canonical way to drive HD's UI. Before it existed, UI was driven by CDP .click() on CSS selectors via hd-cdp.js. This is brittle (selectors drift; multiple localhost:1420 CDP targets) and the selectors below may be stale. Reach for CDP ONLY for an element not yet on the bus — and the better fix is to register it.

Find and click menu items

# Open Adom menu
echo document.querySelector('.logo-button')?.click() | node C:\Users\john\hd-cdp.js

# Find a menu item by text
echo var items=document.querySelectorAll('.dropdown-link,.menu-item');
var target=Array.from(items).find(function(e){return e.textContent.includes('Ports')});
if(target)target.click() | node C:\Users\john\hd-cdp.js

Click setup panel buttons

# Run All
echo document.querySelector('.run-all').click() | node C:\Users\john\hd-cdp.js

# Virgin Reset dropdown
echo document.querySelector('.virgin-reset-btn')?.click() | node C:\Users\john\hd-cdp.js

# Wipe Selected (execute virgin reset)
echo document.querySelector('.virgin-go')?.click() | node C:\Users\john\hd-cdp.js

# Close setup panel
echo document.querySelector('.close-btn,.setup-close')?.click() | node C:\Users\john\hd-cdp.js

Query step states

echo JSON.stringify(Array.from(document.querySelectorAll('.step-row')).map(
function(e,i){
  var icon=e.querySelector('.step-icon');
  return{n:i+1, s:icon?.textContent?.trim()}
})) | node C:\Users\john\hd-cdp.js

CSS Selectors for Key Elements

Element Selector
VS Code iframe iframe.vis-studio-iframe or iframe[title="code"]
Setup panel .setup-panel
Run All button .run-all
Virgin Reset button .virgin-reset-btn
Wipe Selected button .virgin-go
Step rows .step-row
Step icon (✅/❌/○) .step-icon
Step label .step-label
Adom menu button .logo-button
Profile menu button .profile-dropdown-button
Tab bar tab container at top