Hydrogen Desktop (macOS / Lima)
Public Made by Adomby adom
The macOS platform layer for Hydrogen Desktop.
name: hd-ui-mac description: > macOS platform companion to hd-ui — the Apple-specific half of DRIVING HD's UI. Every menu/dialog/panel id, the GET /ui/actions → POST /ui/invoke contract, and registerUiAction live in hd-ui (adom/hd-bootstrap); THIS skill carries only what's macOS-specific: HD's webview is WKWebView with NO Chrome DevTools Protocol, so the legacy CDP .click() path is dead — you drive the UI via the platform-agnostic command bus (hd-ui-command → /ui/_result) and the backend invoke_ui_action RPC (e.g. dom.measure resolves a selector's rect WITHOUT CDP). Mirror of hd-ui-windows (raw CDP clicking, hd-cdp.js, WebView2 CDP). Trigger words — drive HD UI macos, WKWebView, no CDP, dom.measure, hd-ui-command, invoke_ui_action, ui/invoke macos, click HD menu mac, open dialog mac.
hd-ui (macOS) — driving the UI without CDP
This is the macOS half of hd-ui. The window layout, the menu/dialog catalog, the
list of action ids, and the whole GET /ui/actions → POST /ui/invoke workflow are
host-agnostic and live in the generic hd-ui skill — read that first. This skill only
covers what changes on a Mac: how clicks reach the webview when there is no CDP.
The macOS reality — WKWebView has no CDP
On macOS HD's webview is WKWebView, which exposes no Chrome DevTools Protocol
port. The Windows lineage drove the UI by CDP .click() on CSS selectors (hd-cdp.js
→ WebView2's CDP). None of that works here — there's no port to attach to (the same
limitation that makes /eval effectively fire-and-forget on macOS). So on macOS the
command bus isn't merely preferred, it's the only way to operate HD's UI. For an
element that isn't on the bus yet, register it (a 2-line registerUiAction(...) —
see hd-ui) rather than reaching for a selector click; there is nothing to click through.
How the bus crosses to WKWebView — hd-ui-command → /ui/_result
POST /ui/invoke {id} is platform-agnostic precisely because it does not depend on
CDP. The backend (src-tauri/crates/hd-control/src/lib.rs, invoke_ui_action) emits a
Tauri event hd-ui-command {id, args, request_id}; the frontend dispatcher runs
the registered handler and reports back via POST /ui/_result {request_id, ok, value}. The call blocks until that result lands (or the timeout fires). This is the
identical round-trip on every host — but on macOS it's load-bearing, since it's the
substitute for the CDP path Windows still has.
dom.measure — resolve a selector's rect without CDP
The one place the Windows path leaned on CDP that macOS had to re-plumb is geometry.
Where Windows cropped a region screenshot server-side via CDP Page.captureScreenshot
with a clip, macOS can't — so the capture path calls invoke_ui_action(app, "dom.measure", {selector}, 3000) to ask the frontend for the element's rect, then
screencaptures the webview content area and crops the PNG to that rect
(hd-control/src/lib.rs ~5193). dom.measure returns {left, top, width, height, viewport:{width,height}} in CSS px. It's a normal bus action — the macOS analog of CDP's
Runtime.evaluate for "where is this element," reusable by any caller that needs a
selector's geometry without CDP.
NOT here (lives in the Windows companion)
Raw CDP .click() driving, the node C:\Users\…\hd-cdp.js snippets, the WebView2 CDP
port, and the CSS-selector-click playbook are the Windows UI path — see
hd-ui-windows. On macOS that machinery does not exist; drive everything through the
command bus (/ui/actions → /ui/invoke) and register anything that's missing.
---
name: hd-ui-mac
description: >
macOS platform companion to hd-ui — the Apple-specific half of DRIVING HD's UI.
Every menu/dialog/panel id, the GET /ui/actions → POST /ui/invoke contract, and
registerUiAction live in hd-ui (adom/hd-bootstrap); THIS skill carries only what's
macOS-specific: HD's webview is WKWebView with NO Chrome DevTools Protocol, so the
legacy CDP .click() path is dead — you drive the UI via the platform-agnostic
command bus (hd-ui-command → /ui/_result) and the backend invoke_ui_action RPC
(e.g. dom.measure resolves a selector's rect WITHOUT CDP). Mirror of hd-ui-windows
(raw CDP clicking, hd-cdp.js, WebView2 CDP). Trigger words — drive HD UI macos,
WKWebView, no CDP, dom.measure, hd-ui-command, invoke_ui_action, ui/invoke macos,
click HD menu mac, open dialog mac.
---
# hd-ui (macOS) — driving the UI without CDP
This is the **macOS half** of `hd-ui`. The window layout, the menu/dialog catalog, the
list of action ids, and the whole `GET /ui/actions` → `POST /ui/invoke` workflow are
host-agnostic and live in the generic **hd-ui** skill — read that first. This skill only
covers what changes on a Mac: **how clicks reach the webview when there is no CDP.**
## The macOS reality — WKWebView has no CDP
On macOS HD's webview is **WKWebView**, which exposes **no Chrome DevTools Protocol
port**. The Windows lineage drove the UI by CDP `.click()` on CSS selectors (`hd-cdp.js`
→ WebView2's CDP). **None of that works here** — there's no port to attach to (the same
limitation that makes `/eval` effectively fire-and-forget on macOS). So on macOS the
command bus isn't merely *preferred*, it's the **only** way to operate HD's UI. For an
element that isn't on the bus yet, **register it** (a 2-line `registerUiAction(...)` —
see hd-ui) rather than reaching for a selector click; there is nothing to click *through*.
## How the bus crosses to WKWebView — `hd-ui-command` → `/ui/_result`
`POST /ui/invoke {id}` is platform-agnostic precisely because it does **not** depend on
CDP. The backend (`src-tauri/crates/hd-control/src/lib.rs`, `invoke_ui_action`) emits a
Tauri event **`hd-ui-command` `{id, args, request_id}`**; the frontend dispatcher runs
the registered handler and reports back via **`POST /ui/_result` `{request_id, ok,
value}`**. The call blocks until that result lands (or the timeout fires). This is the
identical round-trip on every host — but on macOS it's load-bearing, since it's the
substitute for the CDP path Windows still has.
## `dom.measure` — resolve a selector's rect without CDP
The one place the Windows path leaned on CDP that macOS had to re-plumb is **geometry**.
Where Windows cropped a region screenshot server-side via CDP `Page.captureScreenshot`
with a clip, macOS can't — so the capture path calls **`invoke_ui_action(app,
"dom.measure", {selector}, 3000)`** to ask the *frontend* for the element's rect, then
`screencapture`s the webview content area and crops the PNG to that rect
(`hd-control/src/lib.rs` ~5193). `dom.measure` returns `{left, top, width, height,
viewport:{width,height}}` in CSS px. It's a normal bus action — the macOS analog of CDP's
`Runtime.evaluate` for "where is this element," reusable by any caller that needs a
selector's geometry without CDP.
## NOT here (lives in the Windows companion)
Raw CDP `.click()` driving, the `node C:\Users\…\hd-cdp.js` snippets, the WebView2 CDP
port, and the CSS-selector-click playbook are the **Windows** UI path — see
`hd-ui-windows`. On macOS that machinery does not exist; drive everything through the
command bus (`/ui/actions` → `/ui/invoke`) and register anything that's missing.