Hydrogen Desktop (macOS / Lima)
Public Made by Adomby adom
The macOS platform layer for Hydrogen Desktop.
name: hd-workspace-monitoring
description: >
How Hydrogen Desktop monitors and manages the local workspace machine
(Adom-Workspace) and code-server. Covers the 15s workspace state poll, the
two health levels (Lima VM up, machine running + code-server reachable), the
floaty states (Lima VM not available, machine stopped), auto-start via setup_and_start,
auto-reload of the VS Code iframe, and the lifecycle dialog system. Read BEFORE
touching PanelVisualStudioCode.svelte, ContainerLifecycleDialog.svelte, or any
workspace state handling code. Trigger words: workspace stopped, lima vm not available,
workspace monitoring, machine poll, workspace floaty, start workspace, code-server
reachable, lifecycle dialog, workspace state, Adom-Workspace running.
HD Workspace Monitoring
This is the machine-runtime version (default). The legacy Docker equivalent (
HD_RUNTIME=docker) is in the docker/ bucket.
Architecture
Under the machine runtime the workspace is the Adom-Workspace machine (a
systemd-nspawn machine imported via machinectl import-tar), not a Docker container.
HD monitors workspace health at two levels:
- Lima VM up — is the
hd-builderLima VM itself up and responding on this Mac? - Workspace healthy — is
Adom-Workspacepresent AND running AND is code-server reachable on host port 7380?
The second level is a real reachability check, not just "is the machine present." A resume reality-check (after sleep, or after an HD rebuild/relaunch) requires code-server to actually answer before HD trusts the workspace as healthy — a machine can be running while code-server is dead.
The VS Code panel (PanelVisualStudioCode.svelte) polls workspace state every 15s
and shows appropriate UI for each state. These frontend components survive unchanged
from the Docker era; they now front the machine runtime via the runtime trait.
Workspace State Poll
PanelVisualStudioCode.svelte calls get_container_status (Tauri command) every 15s.
The command dispatches through the runtime trait to the machine impl. Returns a status
struct shaped like:
pub struct ContainerStatus {
pub docker_available: bool, // under the machine runtime: is the Lima VM hd-builder up?
pub image_pulled: bool, // is the Adom-Workspace tarball/machine present?
pub container_exists: bool, // is the machine present (running or stopped)?
pub container_running: bool, // is it running AND code-server reachable on :7380?
pub container_id: Option<String>,
pub error: Option<String>,
}
The field names are inherited from the Docker era; under the machine runtime they map onto the two health levels above (Lima VM availability, then machine-present → machine-running + code-server-reachable).
Floaty States
All floaties appear INSIDE the VS Code panel only — not as full-app modals. They are draggable (grab header to move). The rest of the app (wiki tab, menu, etc.) remains fully interactive. The old Docker floaties ("Docker Desktop not installed/ running") become Lima-VM / machine states under this runtime.
1. Lima VM Not Available (red dot)
- When: the
hd-builderLima VM itself is not up / not responding (level-1 health fails) - Message: "The HD utility VM (hd-builder) is required but not available."
- Action: "Run Setup Steps" button → dispatches
hd-show-setupevent (which walks the user through provisioning the Lima VM) - Color: Red dot in header
2. Workspace Stopped / Not Ready (red dot)
- When: the Lima VM is up but
Adom-Workspaceisn't running, or it's running but code-server isn't reachable on :7380 (container_running == false) - Message: "The Adom workspace is not running."
- Action: "Start Workspace" button → calls
setup_and_startTauri command - Lifecycle dialog: Shows the draggable lifecycle dialog with live setup output
- Auto-reload: After the machine + code-server come up, waits for code-server health, then reloads the VS Code iframe
There is no separate "daemon not running" middle state like Docker had — the machine runtime has no always-on daemon to launch. Either the Lima VM is up or it isn't (state 1), and the workspace is either healthy or it isn't (state 2).
Auto-Start via setup_and_start
The "Start Workspace" path calls Tauri setup_and_start, which (in machine mode)
delegates to MacosVmRuntime::setup_and_start:
- If the machine isn't present yet,
fresh_import= download the goldenadom-golden.tar.gz(from theadom-inc/hd-lima-imagerelease) +machinectl import-tar Adom-Workspace+ start code-server. - If the machine is present but code-server is down, it just (re-)starts code-server.
Importantly, code-server runs as an HD-owned child process (not a detached
nohup) — it dies with HD. So HD also re-ensures code-server on every launch
(look for [macos-startup] re-ensured code-server on launch in the log). Without that,
a freshly relaunched HD would show the machine running but the editor stuck on
"Starting AI Environment" forever, because the previous HD's code-server child was
orphaned. See hd-workspace-lifecycle for the
full lifecycle detail.
Lifecycle Dialog
ContainerLifecycleDialog.svelte — a draggable floating card (no background blur)
that shows live command output for start/stop/restart operations on the machine.
Events
Listens for hd-container-lifecycle CustomEvents on window:
action: 'restart' | 'stop' | 'start'— opens dialog, starts spinneraction: 'step', step: string— appends a log lineaction: 'done'— stops spinner, shows Close button, auto-reloads VS Codeaction: 'stopped'— stops spinner (for stop-only operations)action: 'error', message: string— shows error state
Title
Dynamic based on actionType:
- Restarting: "Workspace Restarting..." → "Restart Complete"
- Stopping: "Stopping Workspace..." → "Workspace Stopped"
- Starting: "Starting Workspace..." → "Workspace Started"
- On error: "Restart/Stop/Start Failed"
VS Code Auto-Reload
After the done event, the dialog polls code-server health (/proxy/8080/) every 5s
for up to 2 minutes. When healthy, it reloads all iframes whose src points at
localhost:7380 (the host-side code-server port), then shows "VS Code iframe reloaded"
and stops.
Tauri Commands
| Command | What it does (machine mode) |
|---|---|
get_container_status |
Returns workspace status — Lima VM up, machine present, running + code-server reachable |
setup_and_start |
MacosVmRuntime::setup_and_start — fresh_import (import machine) + start code-server, up to 10 min timeout |
stop_container |
Stops the workspace (machinectl terminate Adom-Workspace) |
toggle_console |
Show/hide the debug console window |
is_console_visible |
Returns true if console window exists |
There is no launch_docker_desktop equivalent under the machine runtime — there's no daemon to start.
Menu Items (Adom Menu → Workspace Section)
- Restart Workspace —
machinectl terminate Adom-Workspace+ re-ensure code-server; emits lifecycle events, shows dialog - Stop Workspace — terminates the machine; emits lifecycle events, shows dialog, triggers stopped floaty
- Start Workspace — available when stopped (from floaty button or menu)
Settings (Desktop section in Settings dialog)
desktop.show_console_on_startup— boolean, default falsedesktop.launch_on_boot— boolean, default true (auto-start HD when the Mac logs in)
Related skills
- hd-workspace-lifecycle — import/export/remove/terminate, the never-do-a-global-teardown rule, control endpoints
- hd-container-stats — the title-bar CPU/RAM bars and
workspace_stats()probe - hd-networking — port 7380 code-server, control port 47084
---
name: hd-workspace-monitoring
description: >
How Hydrogen Desktop monitors and manages the local workspace machine
(`Adom-Workspace`) and code-server. Covers the 15s workspace state poll, the
two health levels (Lima VM up, machine running + code-server reachable), the
floaty states (Lima VM not available, machine stopped), auto-start via setup_and_start,
auto-reload of the VS Code iframe, and the lifecycle dialog system. Read BEFORE
touching PanelVisualStudioCode.svelte, ContainerLifecycleDialog.svelte, or any
workspace state handling code. Trigger words: workspace stopped, lima vm not available,
workspace monitoring, machine poll, workspace floaty, start workspace, code-server
reachable, lifecycle dialog, workspace state, Adom-Workspace running.
---
# HD Workspace Monitoring
> This is the machine-runtime version (default). The legacy Docker equivalent
> (`HD_RUNTIME=docker`) is in the docker/ bucket.
## Architecture
Under the machine runtime the workspace is the **`Adom-Workspace` machine** (a
systemd-nspawn machine imported via `machinectl import-tar`), not a Docker container.
HD monitors workspace health at two levels:
1. **Lima VM up** — is the `hd-builder` Lima VM itself up and responding on this Mac?
2. **Workspace healthy** — is `Adom-Workspace` present AND running AND is
code-server reachable on host port **7380**?
The second level is a real reachability check, not just "is the machine present."
A resume reality-check (after sleep, or after an HD rebuild/relaunch) requires
code-server to actually answer before HD trusts the workspace as healthy — a machine
can be running while code-server is dead.
The VS Code panel (`PanelVisualStudioCode.svelte`) polls workspace state every 15s
and shows appropriate UI for each state. These frontend components survive unchanged
from the Docker era; they now front the machine runtime via the runtime trait.
## Workspace State Poll
`PanelVisualStudioCode.svelte` calls `get_container_status` (Tauri command) every 15s.
The command dispatches through the runtime trait to the machine impl. Returns a status
struct shaped like:
```rust
pub struct ContainerStatus {
pub docker_available: bool, // under the machine runtime: is the Lima VM hd-builder up?
pub image_pulled: bool, // is the Adom-Workspace tarball/machine present?
pub container_exists: bool, // is the machine present (running or stopped)?
pub container_running: bool, // is it running AND code-server reachable on :7380?
pub container_id: Option<String>,
pub error: Option<String>,
}
```
The field names are inherited from the Docker era; under the machine runtime they map
onto the two health levels above (Lima VM availability, then machine-present →
machine-running + code-server-reachable).
## Floaty States
All floaties appear INSIDE the VS Code panel only — not as full-app modals.
They are draggable (grab header to move). The rest of the app (wiki tab, menu, etc.)
remains fully interactive. The old Docker floaties ("Docker Desktop not installed/
running") become Lima-VM / machine states under this runtime.
### 1. Lima VM Not Available (red dot)
- **When**: the `hd-builder` Lima VM itself is not up / not responding (level-1 health fails)
- **Message**: "The HD utility VM (hd-builder) is required but not available."
- **Action**: "Run Setup Steps" button → dispatches `hd-show-setup` event (which walks
the user through provisioning the Lima VM)
- **Color**: Red dot in header
### 2. Workspace Stopped / Not Ready (red dot)
- **When**: the Lima VM is up but `Adom-Workspace` isn't running, or it's running but
code-server isn't reachable on :7380 (`container_running == false`)
- **Message**: "The Adom workspace is not running."
- **Action**: "Start Workspace" button → calls `setup_and_start` Tauri command
- **Lifecycle dialog**: Shows the draggable lifecycle dialog with live setup output
- **Auto-reload**: After the machine + code-server come up, waits for code-server
health, then reloads the VS Code iframe
There is no separate "daemon not running" middle state like Docker had — the machine
runtime has no always-on daemon to launch. Either the Lima VM is up or it isn't
(state 1), and the workspace is either healthy or it isn't (state 2).
## Auto-Start via `setup_and_start`
The "Start Workspace" path calls Tauri `setup_and_start`, which (in machine mode)
delegates to `MacosVmRuntime::setup_and_start`:
- If the machine isn't present yet, `fresh_import` = download the golden
`adom-golden.tar.gz` (from the `adom-inc/hd-lima-image` release) + `machinectl
import-tar Adom-Workspace` + start code-server.
- If the machine is present but code-server is down, it just (re-)starts code-server.
Importantly, code-server runs as an **HD-owned child process** (not a detached
`nohup`) — it dies with HD. So HD also **re-ensures code-server on every launch**
(look for `[macos-startup] re-ensured code-server on launch` in the log). Without that,
a freshly relaunched HD would show the machine running but the editor stuck on
"Starting AI Environment" forever, because the previous HD's code-server child was
orphaned. See [hd-workspace-lifecycle](../hd-workspace-lifecycle/SKILL.md) for the
full lifecycle detail.
## Lifecycle Dialog
`ContainerLifecycleDialog.svelte` — a draggable floating card (no background blur)
that shows live command output for start/stop/restart operations on the machine.
### Events
Listens for `hd-container-lifecycle` CustomEvents on `window`:
- `action: 'restart' | 'stop' | 'start'` — opens dialog, starts spinner
- `action: 'step', step: string` — appends a log line
- `action: 'done'` — stops spinner, shows Close button, auto-reloads VS Code
- `action: 'stopped'` — stops spinner (for stop-only operations)
- `action: 'error', message: string` — shows error state
### Title
Dynamic based on `actionType`:
- Restarting: "Workspace Restarting..." → "Restart Complete"
- Stopping: "Stopping Workspace..." → "Workspace Stopped"
- Starting: "Starting Workspace..." → "Workspace Started"
- On error: "Restart/Stop/Start Failed"
### VS Code Auto-Reload
After the `done` event, the dialog polls code-server health (`/proxy/8080/`) every 5s
for up to 2 minutes. When healthy, it reloads all iframes whose src points at
`localhost:7380` (the host-side code-server port), then shows "VS Code iframe reloaded"
and stops.
## Tauri Commands
| Command | What it does (machine mode) |
|---|---|
| `get_container_status` | Returns workspace status — Lima VM up, machine present, running + code-server reachable |
| `setup_and_start` | `MacosVmRuntime::setup_and_start` — `fresh_import` (import machine) + start code-server, up to 10 min timeout |
| `stop_container` | Stops the workspace (`machinectl terminate Adom-Workspace`) |
| `toggle_console` | Show/hide the debug console window |
| `is_console_visible` | Returns true if console window exists |
There is no `launch_docker_desktop` equivalent under the machine runtime — there's no daemon to start.
## Menu Items (Adom Menu → Workspace Section)
- **Restart Workspace** — `machinectl terminate Adom-Workspace` + re-ensure code-server; emits lifecycle events, shows dialog
- **Stop Workspace** — terminates the machine; emits lifecycle events, shows dialog, triggers stopped floaty
- **Start Workspace** — available when stopped (from floaty button or menu)
## Settings (Desktop section in Settings dialog)
- `desktop.show_console_on_startup` — boolean, default false
- `desktop.launch_on_boot` — boolean, default true (auto-start HD when the Mac logs in)
## Related skills
- [hd-workspace-lifecycle](../hd-workspace-lifecycle/SKILL.md) — import/export/remove/terminate, the never-do-a-global-teardown rule, control endpoints
- [hd-container-stats](../hd-container-stats/SKILL.md) — the title-bar CPU/RAM bars and `workspace_stats()` probe
- [hd-networking](../hd-networking/SKILL.md) — port 7380 code-server, control port 47084