bootstrap
Adom Hydrogen (macOS / Lima)
Public Made by Adomby adom
The macOS platform layer for Adom Hydrogen.
← Commit history
Publish 0.1.17
22 files changed
+134−182
README.md+28−37SKILL.md+1−1install.sh+6−7package.json+1−1page.json+1−1skills/hydrogen-api-mac/SKILL.md+10−14skills/hydrogen-browser-picker-mac/SKILL.md+3−5skills/hydrogen-captions-mac/SKILL.md+3−4skills/hydrogen-container/SKILL.md+1−1skills/hydrogen-eda-install/SKILL.md+13skills/hydrogen-networking/SKILL.md+2−2skills/hydrogen-notifications-mac/SKILL.md+4−4skills/hydrogen-open-url-mac/SKILL.md+5−12skills/hydrogen-permissions-mac/SKILL.md+4−11skills/hydrogen-port-watcher/SKILL.md+23−41skills/hydrogen-recording-mac/SKILL.md+3−5skills/hydrogen-screen-lock-mac/SKILL.md+3−4skills/hydrogen-self-screenshot-mac/SKILL.md+3−4skills/hydrogen-setup-steps/SKILL.md+1−1skills/hydrogen-setup/SKILL.md+2−2skills/hydrogen-ui-mac/SKILL.md+14−19skills/hydrogen-volume/SKILL.md+3−6README.md+28−37@@ -32,8 +32,8 @@ so `core` stays generic across web + desktop Hydrogen and every host OS. - **Bundled skills:** the macOS-runtime `hd-*` skills — `hydrogen-container`, `hydrogen-container-stats`, `hydrogen-networking`, `hydrogen-ports`, `hydrogen-port-watcher`, `hydrogen-setup`, `hydrogen-setup-steps`, `hydrogen-topology`, `hydrogen-volume`, `hydrogen-workspace-lifecycle`,- `hydrogen-workspace-monitoring` (the Lima/nspawn analogs of the Windows layer's WSL2 set,- sourced from `adom-hydrogen/skills/public-facing/machine/`).+ `hydrogen-workspace-monitoring` (sourced from+ `adom-hydrogen/skills/public-facing/machine/`). - **install script:** deploys those skills into `~/.claude/skills/` on top of the generic layer, and installs the **`shot`** helper (`~/.local/bin/shot`) — one-call, token-efficient workspace screenshots that print only a PNG path (see@@ -44,50 +44,41 @@ so `core` stays generic across web + desktop Hydrogen and every host OS. deploy scripts explicitly (`core → hd-bootstrap → hydrogen-mac-bootstrap`) so a fresh skills release actually reaches an already-baked machine. -## The runtime difference vs. the Windows layer+## The macOS runtime -The **workspace is Linux in both cases** — the layers differ only in *where* that-Linux runs and how the host reaches it:+The **workspace is always Linux**; on a Mac that Linux runs in a local VM: -| | Windows layer | macOS layer (this) |-|---|---|---|-| Linux host | WSL2 Ubuntu distro | Lima VM (`hd-builder`) → nspawn machine (`Adom-Workspace`) |-| Provisioning | `wsl --import` of the golden WSL2 image | `machinectl import-tar` of the golden Lima image |-| Host↔workspace | `\\wsl$` share + WSL networking | Lima virtiofs share + `adom-host` gateway |-| Golden image | `hd-wsl2-image` | `hd-lima-image` |+| | macOS layer (this) |+|---|---|+| Linux host | Lima VM (`hd-builder`) → nspawn machine (`Adom-Workspace`) |+| Provisioning | `machinectl import-tar` of the golden Lima image |+| Host↔workspace | Lima virtiofs share + `adom-host` gateway |+| Golden image | `hd-lima-image` | ## The mixed-skill split (`<name>-mac` companions) -`adom/hydrogen-bootstrap` carries the **31 platform-generic** `hd-*` skills. The Windows-layer split **13 mixed** skills into `<name>-windows` companions (e.g.-`hd-api-windows`, `hd-notifications-windows`, `hd-setup-windows`) — the generic core-stays in `hd-bootstrap`, the Windows half drops into `hydrogen-windows-bootstrap`. This-layer carries the parallel **macOS halves** in `skills/<name>-mac/`.+`adom/hydrogen-bootstrap` carries the **31 platform-generic** `hd-*` skills. **13 mixed**+skills are split per platform: the generic core stays in `hd-bootstrap`, and each+platform layer carries its own half. This layer carries the **macOS halves** in+`skills/<name>-mac/`. **Companions authored (11):**-- `hydrogen-api-mac` — `adom-host` gateway, `~/.adom/hd-control-url` discovery, vz-no-loopback, `/workspace/*` (nspawn) endpoints (mirror of `hd-api-windows`' `/wsl/*` tables).+- `hydrogen-api-mac` — `adom-host` gateway, `~/.adom/hd-control-url` discovery, vz-no-loopback, `/workspace/*` (nspawn) endpoints. - `hydrogen-api-key-mac` — diagnose/repair the injected `/var/run/adom/api-key` session token (adom-cli 401s, tmpfs wipe on machine reboot, pre-0.1.148 post-auth gap): pull via `GET /auth-token`, prompt the user to reauthorize, or trigger the `inject-api-key` setup step.-- `hydrogen-notifications-mac` — Notification Center toasts + emergency Dock-bounce + the Notifications grant (mirror of `hd-notifications-windows`' WinRT/AUMID).-- `hydrogen-recording-mac` — the native recorder is `#[cfg(windows)]`, so on macOS recording is in-app getDisplayMedia / pup / AD relay; ScreenCaptureKit native recorder **not yet built** (honest gap). Screen Recording TCC.-- `hydrogen-screen-lock-mac` — IOKit `IOPMAssertionCreateWithName`/`PreventUserIdleDisplaySleep`, `pmset -g assertions`, `caffeinate` (vs `SetThreadExecutionState`).-- `hydrogen-self-screenshot-mac` — `screencapture`/CoreGraphics + CDP `Page.captureScreenshot`; per-panel crop resolves the rect via the `dom.measure` RPC (no CDP on WKWebView) + `image`-crate crop (vs Win32 `PrintWindow`).-- `hydrogen-browser-picker-mac` — WKWebView-over-`localhost` interception + LaunchServices `open -a` native browsers (vs WebView2/COM 6-layer interception).-- `hydrogen-permissions-mac` — the macOS TCC model (Screen Recording, Accessibility, Automation, Camera/Mic) + preflight/relaunch (vs UAC).-- `hydrogen-open-url-mac` — `open`/`open -a … --new-window` LaunchServices launch + control-URL discovery (vs `chrome.exe`/`msedge.exe`).-- `hydrogen-ui-mac` — driving the UI via the `hd-ui-command`→`/ui/_result` command bus + `invoke_ui_action` (WKWebView has no CDP; raw CDP clicking is Windows-only).-- `hydrogen-captions-mac` — workspace caption is platform-neutral; the desktop overlay (`desktop_caption`) is a **Windows-only** stub on macOS (honest gap).--> Reconcile the exact 13-skill set against `adom/hydrogen-windows-bootstrap`'s companions-> (its source is `--hide-source` sealed; read it from a workspace with org access).-> The machine-bucket skills above ship whole (they map to the Windows layer's *clean*-> skills, not its mixed companions).+- `hydrogen-notifications-mac` — Notification Center toasts + emergency Dock-bounce + the Notifications grant.+- `hydrogen-recording-mac` — Hydrogen's native recorder does not exist on macOS, so recording is in-app getDisplayMedia / pup / relay; ScreenCaptureKit native recorder **not yet built** (honest gap). Screen Recording TCC.+- `hydrogen-screen-lock-mac` — IOKit `IOPMAssertionCreateWithName`/`PreventUserIdleDisplaySleep`, `pmset -g assertions`, `caffeinate`.+- `hydrogen-self-screenshot-mac` — `screencapture`/CoreGraphics + CDP `Page.captureScreenshot`; per-panel crop resolves the rect via the `dom.measure` RPC (no CDP on WKWebView) + `image`-crate crop.+- `hydrogen-browser-picker-mac` — WKWebView-over-`localhost` interception + LaunchServices `open -a` native browsers.+- `hydrogen-permissions-mac` — the macOS TCC model (Screen Recording, Accessibility, Automation, Camera/Mic) + preflight/relaunch.+- `hydrogen-open-url-mac` — `open`/`open -a … --new-window` LaunchServices launch + control-URL discovery.+- `hydrogen-ui-mac` — driving the UI via the `hd-ui-command`→`/ui/_result` command bus + `invoke_ui_action` (WKWebView has no CDP).+- `hydrogen-captions-mac` — workspace caption is platform-neutral; the desktop overlay (`desktop_caption`) is not implemented on macOS (honest gap). > Note: the macOS-runtime skills in `skills/` that are **whole** (the `machine/` bucket-> — `hydrogen-setup`, `hydrogen-container`, …) correspond to the Windows layer's *clean* skills, not-> its mixed companions, so they ship complete rather than as `-mac` halves. The exact-> 13-skill set should be reconciled against `adom/hydrogen-windows-bootstrap`'s companions-> (its source is `--hide-source` sealed; read it from a workspace with org access).+> — `hydrogen-setup`, `hydrogen-container`, …) are platform-clean skills, so they ship+> complete rather than as `-mac` halves. The exact 13-skill mixed set should be+> reconciled against the sibling platform layers' companions. -> NOTE — naming: the canonical sibling slug is **`hydrogen-mac-bootstrap`** (as referenced-> by `adom/hydrogen-windows-bootstrap`'s own description and stack diagram), not+> NOTE — naming: the canonical slug for this layer is **`hydrogen-mac-bootstrap`**, not > `hd-macos-bootstrap`.
SKILL.md+1−1@@ -11,4 +11,4 @@ Ubuntu / systemd-nspawn workspace to the macOS Adom Hydrogen runtime: it pulls `adom/hydrogen-bootstrap` (generic Hydrogen) + `adom/adom-workspace-updater`, and deploys the macOS-runtime `hd-*` skills. -See README.md for the layered stack and the runtime differences vs. the Windows layer.+See README.md for the layered stack and the macOS runtime model.
install.sh+6−7@@ -4,9 +4,8 @@ # Runs as the workspace user after the dependency tree (adom/hd-bootstrap → adom/core, # adom/adom-workspace-updater) has installed. The generic adom/hd-bootstrap layer already # deployed the 31 platform-generic hd-* skills + the shared code-server config; THIS layer-# only adds the macOS-runtime specifics on top. Mirrors the platform-layer role of-# adom/hd-windows-bootstrap (which deploys the WSL2-runtime skills), and the config sections of-# hd-wsl2-image/image/bake-hd-setup.sh adapted for the Lima/nspawn machine.+# only adds the macOS-runtime specifics on top: the Lima/nspawn-runtime skills and the+# mac config seed for the machine. # # Idempotent: safe to re-run (a live `adompkg install`) — every step overwrites in place. set -euo pipefail@@ -16,22 +15,22 @@ SKILLS="$HOME/.claude/skills" log() { printf '[hydrogen-mac-bootstrap] %s\n' "$*"; } -# ── deploy the bundled macOS-runtime hd-* skills (flat into ~/.claude/skills/<name>/) ────────+# ── deploy the bundled macOS-runtime hydrogen-* skills (flat into ~/.claude/skills/<name>/) ──────── mkdir -p "$SKILLS" n=0-for d in "$HERE"/skills/hd-*/; do+for d in "$HERE"/skills/hydrogen-*/; do [ -f "${d}SKILL.md" ] || continue name="$(basename "$d")" mkdir -p "$SKILLS/$name" cp -f "${d}SKILL.md" "$SKILLS/$name/SKILL.md" n=$((n + 1)) done-log "deployed $n macOS-runtime hd-* skills -> $SKILLS"+log "deployed $n macOS-runtime hydrogen-* skills -> $SKILLS" [ "$n" -gt 0 ] || { echo "[hydrogen-mac-bootstrap] ERROR: no skills deployed" >&2; exit 1; } # ── code-server workbench seed (trusted domains '*' + activity-bar unpin), macOS path ──────── # The generic layer seeds the workbench; re-assert here so a mac-only re-install converges it.-# code-server's data dir is the same in the Lima/nspawn machine as on WSL2 (Linux workspace).+# code-server's data dir is the standard Linux-workspace path inside the Lima/nspawn machine. WB_DIR="$HOME/.local/share/code-server" if [ -d "$WB_DIR" ]; then log "code-server workbench present at $WB_DIR (trusted-domains seed handled by adom/hd-bootstrap)"
package.json+1−1@@ -4,7 +4,7 @@ "type": "bootstrap", "title": "Adom Hydrogen (macOS / Lima)", "brief": "The macOS platform layer for Adom Hydrogen.",- "version": "0.1.16",+ "version": "0.1.17", "description": "The macOS platform layer for Adom Hydrogen, where the workspace runs in a Lima Ubuntu VM hosting the Adom-Workspace systemd-nspawn machine. Depends on adom/hydrogen-bootstrap (the platform-generic Hydrogen layer) and adds everything specific to the Lima/nspawn runtime: the container/networking/ports/setup/topology/volume/workspace-lifecycle hydrogen-* skills (the macOS-runtime bucket), the in-machine workspace-updater daemon, and the macOS code-server workbench seed. Sibling layers adom/hydrogen-windows-bootstrap (WSL2) and adom/hydrogen-ubuntu-bootstrap depend on the same adom/hydrogen-bootstrap. This is the package the golden Lima image installs.", "org": "adom", "tags": [
page.json+1−1@@ -4,7 +4,7 @@ "slug": "hydrogen-mac-bootstrap", "title": "Adom Hydrogen (macOS / Lima)", "brief": "The macOS platform layer for Adom Hydrogen.",- "version": "0.1.16",+ "version": "0.1.17", "license": "proprietary", "visibility": "public", "metadata": {
skills/hydrogen-api-mac/SKILL.md+10−14@@ -5,8 +5,8 @@ description: > control API. The full endpoint catalog lives in hydrogen-api (adom/hd-bootstrap); THIS skill carries only what differs on macOS: the adom-host gateway (vz doesn't mirror loopback), the ~/.adom/hd-control-url discovery file, Hydrogen binding 0.0.0.0, and the- nspawn machine-runtime endpoints (the /workspace/* routes, /wsl/* names kept for- wire-compat). Mirror of hd-api-windows (the /wsl/* WSL networking tables). Trigger+ nspawn machine-runtime endpoints (the /workspace/* routes, legacy /wsl/* route names+ kept for wire-compat). Trigger words — hydrogen control api macos, adom-host, hd-control-url, reach Hydrogen from the workspace, machine runtime endpoints, vz loopback, workspace health macos. ---@@ -36,15 +36,16 @@ CTRL="$(cat ~/.adom/hd-control-url)" # e.g. http://adom-host:<control> curl -sf "$CTRL/health" ``` -Never hard-code the port or assume `127.0.0.1` from inside the machine — that's the #1-macOS-specific failure when porting a Windows playbook that used a `\\wsl$`/loopback-path.+Never hard-code the port or assume `127.0.0.1` from inside the machine — the `vz` VM+does not mirror host loopback, so a loopback-based playbook fails here. The discovery+file is the only supported path. ## Machine-runtime endpoints The default macOS runtime is the **nspawn machine** (not Docker). Hydrogen exposes the-workspace-runtime routes under `/workspace/*` — and **keeps the `/wsl/*` route names as-wire-compat aliases**, so a caller written against the Windows tables still resolves:+workspace-runtime routes under `/workspace/*` — and **keeps the legacy `/wsl/*` route+names as wire-compat aliases**, so a caller written against the older route names still+resolves: | Method | Path | Notes | |---|---|---|@@ -53,11 +54,6 @@ wire-compat aliases**, so a caller written against the Windows tables still reso | GET | `/container-status` | runtime available, image/machine present, workspace running | `/test/probe-dialogs` classifies **macOS permission prompts** (Screen Recording /-Accessibility / installer pkg) as blockers — the macOS analog of the Windows-UAC/installer dialogs.+Accessibility / installer pkg) as blockers. -## NOT here (lives in the Windows companion)--The `\\wsl$` share paths, WSL2 port-proxy / `netsh` forwarding, and the Windows-loopback-mirroring assumptions are in `hd-api-windows`. On macOS reachability is the-`adom-host` gateway + `~/.adom/hd-control-url`, full stop.+On macOS reachability is the `adom-host` gateway + `~/.adom/hd-control-url`, full stop.
skills/hydrogen-browser-picker-mac/SKILL.md+3−5@@ -7,8 +7,7 @@ description: > fresh-window toggle, and the prefs API all live in hydrogen-browser-picker (adom/hd-bootstrap); THIS skill carries only what's wired differently on macOS: the top frame is a WKWebView served over http://localhost (not WebView2), and the- native-browser targets are launched via LaunchServices (`open -a`). Mirror of- hd-browser-picker-windows (the WebView2 / ICoreWebView2 COM / 6-layer machinery).+ native-browser targets are launched via LaunchServices (`open -a`). Trigger words — browser picker macos, WKWebView interception, open -a, native browser macos, Safari Chrome Arc Edge, localhost top frame, shell.open macos. ---@@ -65,10 +64,9 @@ The "open in native browser" path still ultimately calls the Tauri shell plugin, both `shell:allow-open` AND `shell:default` must be in both capability files — that requirement is platform-agnostic and is covered in the generic skill. -## NOT here (lives in the Windows companion)+## Not applicable on macOS The WebView2 / `ICoreWebView2` COM detail — the 6 named interception layers, the `AddScriptToExecuteOnDocumentCreated` cross-origin-iframe script, the `ICoreWebView2_11` context-menu wiring, the webview2-com 0.38 `.cast()` patterns, and-launching `chrome.exe`/`msedge.exe` by resolved path — is the Windows lineage; see-`hd-browser-picker-windows`. On macOS it's WKWebView + `open -a`, full stop.+launching `chrome.exe`/`msedge.exe` by resolved path — is the Windows lineage;. On macOS it's WKWebView + `open -a`, full stop.
skills/hydrogen-captions-mac/SKILL.md+3−4@@ -7,8 +7,7 @@ description: > (adom/hd-bootstrap) and are platform-neutral; THIS skill carries only the one macOS difference: the full-DESKTOP overlay (adom-desktop desktop_caption) is a Win32 click-through window and is NOT implemented on macOS yet (the non-Windows build is a- stub). The workspace caption (adom-cli hydrogen caption) works the same on macOS.- Mirror of hd-captions-windows. Trigger words — caption macos, desktop_caption macos,+ stub). The workspace caption (adom-cli hydrogen caption) works the same on macOS. Trigger words — caption macos, desktop_caption macos, desktop overlay mac, screen overlay mac, caption not showing mac, click-through caption mac. --- @@ -49,9 +48,9 @@ caption overlay** at this time. (The `caption` capability that `adom-desktop sta advertises reflects the Windows host overlay; treat it as Windows-only until a macOS overlay ships.) -## NOT here (lives in the Windows companion)+## Not applicable on macOS The Win32 always-on-top click-through layered-window implementation — `caption.rs`'s `#[cfg(windows)]` `show_caption_window` / `destroy_captions`, the `AdomCaptionOverlay` window class, and the id-as-window-title routing that backs `adom-desktop-desktop_caption` — is the **Windows** delivery; see `hd-captions-windows`.+desktop_caption` — is the **Windows** delivery;.
skills/hydrogen-container/SKILL.md+1−1@@ -21,7 +21,7 @@ You are running inside the **`Adom-Workspace` machine** managed by Adom Hydrogen | code-server binary | `/usr/lib/code-server/bin/code-server` | | Extensions dir | `~/.local/share/code-server/extensions/` | | Settings | `~/.local/share/code-server/User/settings.json` |-| Machine default user | `adom` (UID 1001; under systemd-nspawn there's no wsl.conf — the default user comes from the machine config / nsenter `-S 1001 -G 1001`) — in-machine exec via `limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash -lc '<cmd>'`; root variant drops `-S 1001 -G 1001` |+| Machine default user | `adom` (UID 1001; under systemd-nspawn the default user comes from the machine config / nsenter `-S 1001 -G 1001`) — in-machine exec via `limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash -lc '<cmd>'`; root variant drops `-S 1001 -G 1001` | | Work user | `adom` (UID 1001, passwordless sudo, home `/home/adom`) | | Workspace | `/home/adom/project` (lives directly in the machine's ext4 filesystem) | | Pre-installed | Node 18 + npm, Python 3.12, git, gh, curl, wget, jq, build-essential, cmake, pkg-config, libssl-dev |
skills/hydrogen-eda-install/SKILL.md+13@@ -62,6 +62,19 @@ Autodesk account). But don't just paste a link either: No bridge exists yet. Say so honestly, and pitch co-building a bridge (see hydrogen-eda-discovery — the KiCad/Fusion bridges are the reference implementations). +### Detecting no-bridge EDA tools on macOS++There is no bridge verb for these, so detect by install path and running+process via `adom-bridge-cli run_script`: scan `/Applications` (and+`~/Applications`) for the app bundles, plus `pgrep` for a running instance.++```bash+SCRIPT=$(printf '%s' 'ls -d /Applications/*Altium* /Applications/*OrCAD* /Applications/*Cadence* /Applications/*EAGLE* ~/Applications/*Altium* 2>/dev/null; pgrep -il "altium|orcad|allegro|eagle" 2>/dev/null' | base64)+adom-bridge-cli run_script "{\"interpreter\":\"bash\",\"scriptB64\":\"$SCRIPT\"}"+```++Treat empty output as a timeout or probe failure, not a negative result.+ ## Related skills - `hydrogen-bridges` — full bridge ecosystem reference (status, CLI, Bridge Manager)
skills/hydrogen-networking/SKILL.md+2−2@@ -19,8 +19,8 @@ description: > ## Core Principle: expose `0.0.0.0` listeners to the Mac The Hydrogen workspace is the `Adom-Workspace` machine (a systemd-nspawn machine booted-inside the `hd-builder` Lima VM), not a Docker container. macOS does **not** do-WSL2-style magic loopback mirroring — vz does NOT mirror loopback. Instead, Lima+inside the `hd-builder` Lima VM), not a Docker container. The Apple `vz` VM does+**NOT** mirror loopback between host and machine. Instead, Lima exposes the machine's listeners to the Mac: **any service that binds `0.0.0.0:<port>` inside the workspace machine is reachable at `127.0.0.1:<sameport>` on the Mac** — no Docker `-p` mapping, no proxy hop
skills/hydrogen-notifications-mac/SKILL.md+4−4@@ -6,7 +6,7 @@ description: > payload shape, levels, and /ui/toast live in hydrogen-notifications (adom/hd-bootstrap); THIS skill carries only the macOS delivery mechanics: Notification Center toasts, the emergency Dock-icon attention bounce, and the System Settings → Notifications- grant. Mirror of hd-notifications-windows (WinRT/AUMID). Trigger words — macos+ grant. Trigger words — macos notification, notification center, dock bounce, request attention macos, allow notifications macos, toast on mac. ---@@ -31,7 +31,7 @@ skill only documents what's Apple-specific. - **Identity.** Toasts surface under the **"Adom"** title (Hydrogen prefixes `title` with `"Adom: "` unless it already starts with "Adom"), and the notification is attributed to Hydrogen's **app bundle** — not via a Start-Menu-shortcut AUMID (that's the Windows- path; see hd-notifications-windows).+ path). ## macOS gotcha — the Notifications grant @@ -41,8 +41,8 @@ macOS gates notifications per-app: the user must allow **Adom Hydrogen** under "always works" toast. Unlike Screen Recording / Accessibility, Hydrogen does not block setup on it; it's best-effort. -## NOT here (lives in the Windows companion)+## Not applicable on macOS WinRT toast templates, the Start-Menu-shortcut **AUMID** wiring, and taskbar flash are-the Windows delivery — see `hd-notifications-windows`. Do not apply that machinery on+the Windows delivery. Do not apply that machinery on macOS.
skills/hydrogen-open-url-mac/SKILL.md+5−12@@ -8,8 +8,7 @@ description: > (adom/hd-bootstrap); THIS skill carries only the macOS native-browser mechanics: launching via LaunchServices (`open` / `open -a "<App Name>"` / `--new-window` fresh windows), macOS browser-profile dirs, and the control-URL discovery file- (~/.adom/hd-control-url). Mirror of hd-open-url-windows (chrome.exe/msedge.exe by- path). Trigger words — open url macos, open -a, native browser mac, Safari Chrome+ (~/.adom/hd-control-url). Trigger words — open url macos, open -a, native browser mac, Safari Chrome Arc Edge, fresh window mac, browser profiles mac, hd-control-url. --- @@ -54,14 +53,8 @@ LaunchServices, not by resolving an `.exe`: `/open-in-profile {browser, profileDir}` can target the **work** profile (where saved logins live). On macOS those profiles live under the app's Application Support dir (e.g. `~/Library/Application Support/Google/Chrome/<Profile>`,-`…/Microsoft Edge/<Profile>`), as opposed to the Windows `%LOCALAPPDATA%\…\User Data`-layout. Discover them via the endpoint rather than assuming a path or browser — don't-hard-code `chrome`/`edge`.+`…/Microsoft Edge/<Profile>`). Discover them via the endpoint rather than assuming a+path or browser — don't hard-code `chrome`/`edge`. -## NOT here (lives in the Windows companion)--Launching `chrome.exe` / `msedge.exe` by resolved path (`find_browser_exe`), the-`%LOCALAPPDATA%\…\User Data\<Profile>` profile-dir layout, and the Windows-`--new-window` / `--profile-directory` exe invocation are the Windows native-browser-path — see `hd-open-url-windows`. On macOS it's LaunchServices (`open` / `open -a`) with-app-name targets.+On macOS the native-browser path is LaunchServices (`open` / `open -a`) with app-name+targets, never a resolved executable path.
skills/hydrogen-permissions-mac/SKILL.md+4−11@@ -9,7 +9,7 @@ description: > Automation, Camera, Microphone) granted under System Settings → Privacy & Security, how Hydrogen preflights/requests them (CGPreflightScreenCaptureAccess, AXIsProcessTrustedWithOptions), and that some need a relaunch / a stable signing- identity to stick. Mirror of hd-permissions-windows (UAC, no per-feature gate).+ identity to stick. Trigger words — macos permissions, TCC, screen recording permission, accessibility permission, automation permission, privacy and security, AXIsProcessTrusted, CGPreflightScreenCaptureAccess, grant accessibility, relaunch to take effect.@@ -26,9 +26,9 @@ the macOS **OS-level** gates that sit *separately* underneath that auto-grant. ## Two different layers — don't conflate them - **In-webview permissions** (mic/camera/clipboard/etc.): on macOS Hydrogen's webview is- **WKWebView**, which grants in-page media capture with no per-site prompt — same- user-facing result as the Windows WebView2 `PermissionRequested` auto-grant. This is- the generic skill's territory.+ **WKWebView**, which grants in-page media capture with no per-site prompt — the+ auto-grant behavior described in the generic skill. This is the generic skill's+ territory. - **OS-level TCC permissions:** macOS still gates Hydrogen's *process* with the system-wide TCC (Transparency, Consent & Control) model. These are real system prompts and live under **System Settings → Privacy & Security**. The webview auto-grant does NOT bypass@@ -68,10 +68,3 @@ mid-cascade (`setup_steps_macos.rs`), and can deep-link the user to the exact pa - **Graceful degradation:** if Accessibility / Screen Recording are off, Hydrogen still opens the sign-in page and starts the flow — the user just approves the browser page themselves (no auto-press). It does not hard-block on these (`setup_steps_macos.rs`).--## NOT here (lives in the Windows companion)--Windows has no per-feature OS gate equivalent to TCC — the analog is **UAC** (elevation-for the installer / WSL2 setup), and the WebView2 `PermissionRequested` auto-grant-handler. Screen Recording / Accessibility / Automation consent has no Windows-counterpart. See `hd-permissions-windows`.
skills/hydrogen-port-watcher/SKILL.md+23−41@@ -130,7 +130,6 @@ into the machine, NOT `docker cp`/`docker exec`: ```bash # Stage the script into the Lima VM, then install it into the machine via nsenter.-# (No \\wsl$ share / wsl cat exists on macOS — copy into the VM, then nsenter.) limactl copy port-watcher.sh hd-builder:/tmp/port-watcher.sh limactl shell hd-builder -- sudo nsenter -t <leader> -a -- bash -lc \ 'cp /tmp/port-watcher.sh /usr/local/bin/port-watcher.sh && chmod +x /usr/local/bin/port-watcher.sh'@@ -169,38 +168,23 @@ Hydrogen. ## The forwarding layers -There are distinct forwarding mechanisms. The `/proc/net/tcp` watcher above-is **Layer 2** — and on macOS it is the **primary** path. Layer 1 (the-navigation-interception localhost proxy) is **Windows-only** and does NOT run on-macOS — see the note below.--### Layer 1 — the navigation-interception proxy (Windows-only; NOT active on macOS)--On Windows, Hydrogen intercepts top-level WebView2 navigations via-`setup_frame_navigation_interception()` (`hd-app/src/lib.rs`, `#[cfg(windows)]`).-On every navigation it runs `extract_oauth_callback_port()`, which-**triple-URL-decodes** the target URL (`urlencoding::decode` x3) and scans each-decode layer — plus the raw and the percent-encoded-`redirect_uri=http%3A%2F%2Flocalhost%3A…` form — for-`redirect_uri=http://localhost:<port>`. When it finds one it calls-`start_oauth_callback_proxy(port)`, which **pre-binds** `127.0.0.1:<port>` on the-host and waits up to ~5 min for one inbound request, then forwards the full path-into the machine via code-server (`http://localhost:<code_server_port>/proxy/<port>/<path>`)-and streams the response back to the browser.--**This interceptor does NOT exist on macOS.** It depends on WebView2's-`ICoreWebView2` navigation events; Hydrogen's macOS webview is **WKWebView**, which-exposes no equivalent navigation-interception (the same CDP gap that makes-`/eval` fire-and-forget on macOS). So on macOS the *automatic* zero-latency-pre-bind doesn't happen — the **port watcher (Layer 2) is the primary path**,-with the manual `POST /start-oauth-proxy` endpoint (Layer 3) as the explicit-fallback. The `/start-oauth-proxy` + `/oauth/callback` endpoints themselves are-cross-platform and work the same on macOS.+There are distinct forwarding mechanisms. On macOS the `/proc/net/tcp` watcher+above is the **primary** path; the manual endpoints below are the explicit+fallback.++### No automatic OAuth pre-bind on macOS++Hydrogen's macOS webview is **WKWebView**, which exposes no navigation-interception+hook (the same CDP gap that makes `/eval` fire-and-forget on macOS). So there is+no *automatic* zero-latency pre-bind of OAuth callback ports when an OAuth URL+leaves the webview — the **port watcher is the primary path**, with the manual+`POST /start-oauth-proxy` endpoint as the explicit fallback. The+`/start-oauth-proxy` + `/oauth/callback` endpoints themselves are cross-platform+and work the same on macOS. **Control / callback endpoints** (Hydrogen control API): - `POST /start-oauth-proxy` — manually pre-bind a callback port (on macOS this is- the explicit way to get the Layer-1 effect, since the navigation interceptor- doesn't run).+ the explicit way to get the pre-bind effect). - `GET /oauth/callback` — Hydrogen's own built-in callback receiver (used by the Claude Code PKCE flow); do not call directly. @@ -213,21 +197,19 @@ need its callback port (…) mapped to the host."* Seeing that page in a browser means the proxy bound but the machine-side proxy hop failed — check the Hydrogen log for `[oauth-proxy]` lines and that code-server is alive. -### Layer 2 — the port watcher (`/proc/net/tcp` daemon — the primary path on macOS)+### The port watcher (`/proc/net/tcp` daemon — the primary path on macOS) -The bash daemon documented above. On macOS it is the workhorse (Layer 1's-navigation interceptor is Windows-only): it surfaces new callback ports —-including `127.0.0.1`-only callback servers Lima silently won't expose — and asks-Hydrogen to proxy them. Note: when an app has already registered its port via the-adom-port-hints protocol, the watcher skips it (it only owns the fallback for-third-party extensions that don't know Hydrogen exists).+The bash daemon documented above. On macOS it is the workhorse: it surfaces new+callback ports — including `127.0.0.1`-only callback servers Lima silently won't+expose — and asks Hydrogen to proxy them. Note: when an app has already registered+its port via the adom-port-hints protocol, the watcher skips it (it only owns the+fallback for third-party extensions that don't know Hydrogen exists). -### Layer 3 — manual+### Manual `POST /start-oauth-proxy` or `POST /port-forward` (or-`adom-cli port-forward register`) for cases the watcher misses (on macOS, where-the Windows-only navigation interceptor doesn't run, this is the explicit-pre-bind path).+`adom-cli port-forward register`) for cases the watcher misses; this is the+explicit pre-bind path on macOS. ## Port Conflicts
skills/hydrogen-recording-mac/SKILL.md+3−5@@ -7,8 +7,7 @@ description: > in hydrogen-recording (adom/hd-bootstrap); THIS skill carries only what's true on macOS: Hydrogen's native recorder is NOT available here (it's #![cfg(windows)]), so recording goes through the in-app getDisplayMedia recorder, pup per-tab, or the AD desktop- relay — and the Screen Recording TCC grant gates the desktop paths. Mirror of- hd-recording-windows (the native WGC/DXGI recorder). Trigger words — record macos,+ relay — and the Screen Recording TCC grant gates the desktop paths. Trigger words — record macos, screen recording mac, record kicad mac, native recording windows-only, screencapturekit, avfoundation, getdisplaymedia mac, screen recording permission, tcc grant recording, desktop_record_start macos.@@ -63,11 +62,10 @@ Recording** must allow the recording app. Without that grant the capture is blac empty even though the call "succeeds." If a desktop recording comes back blank, check the Screen Recording grant first. -## NOT here (lives in the Windows companion)+## Not applicable on macOS The native WGC/DXGI recorder — `Windows.Graphics.Capture` per-window + DXGI Desktop Duplication full-screen → Media Foundation hardware H.264/H.265 → mp4 in `~/project/recordings/`, the `/recording/native/*` endpoints, `adom-cli hydrogen recording start --share`, and per-window `{source:"window:X"}` scoping (no picker, no-"you're sharing" banner, no wake-lock) — are all Windows-only; see-`hd-recording-windows`. None of that machinery exists on macOS.+"you're sharing" banner, no wake-lock) — are all Windows-only;. None of that machinery exists on macOS.
skills/hydrogen-screen-lock-mac/SKILL.md+3−4@@ -7,8 +7,7 @@ description: > the contention guard) lives in hydrogen-screen-lock (adom/hd-bootstrap); THIS skill carries only the macOS power-assertion mechanics: the IOKit IOPMAssertion (PreventUserIdleDisplaySleep), diagnosing the holder with `pmset -g assertions`, and- `caffeinate`. Mirror of hd-screen-lock-windows (SetThreadExecutionState /- ES_DISPLAY_REQUIRED, `powercfg /requests`). Trigger words — macos display wake-lock,+ `caffeinate`. Trigger words — macos display wake-lock, iopmassertion, preventuseridledisplaysleep, pmset assertions, caffeinate, display won't sleep mac, screensaver blocked mac, screen capture assertion safari. ---@@ -53,9 +52,9 @@ pmset -g assertions # look for a PreventUserIdleDisplaySleep holder `caffeinate -d`); if you see it in `pmset -g assertions`, something invoked it on purpose — it is not Hydrogen. -## NOT here (lives in the Windows companion)+## Not applicable on macOS The Windows wake-lock mechanics — `SetThreadExecutionState(ES_DISPLAY_REQUIRED)` as the lock primitive, and diagnosing the holder with `powercfg /requests` (the elevated-`DISPLAY:` section) — are in `hd-screen-lock-windows`. On macOS it's the IOKit+`DISPLAY:` section) — do not exist on macOS. Here it's the IOKit `IOPMAssertion` + `pmset -g assertions`, full stop.
skills/hydrogen-self-screenshot-mac/SKILL.md+3−4@@ -10,7 +10,7 @@ description: > `screencapture` CLI / CoreGraphics window path, the CDP `Page.captureScreenshot` content grab, how the per-panel selector crop resolves the rect via `dom.measure` (WKWebView has no CDP) and crops with the image crate, and the Screen Recording TCC- grant. Mirror of hd-self-screenshot-windows (Win32 PrintWindow/BitBlt). Trigger+ grant. Trigger words — screenshot hydrogen mac, shot helper, token efficient screenshot, screencapture cli, coregraphics screenshot, wkwebview no cdp, dom.measure crop, page.capturescreenshot mac, screen recording permission screenshot, tcc screenshot@@ -85,9 +85,8 @@ that grant a window/screen capture comes back **black or empty** even though the "succeeds." If screenshots are blank, check the Screen Recording grant first — it's the same grant the desktop recording paths need ([hydrogen-recording-mac]). -## NOT here (lives in the Windows companion)+## Not applicable on macOS The Win32 capture primitives — **`PrintWindow`** (per-window, works for backgrounded-windows) and **`BitBlt`** — are the Windows self-screenshot mechanics; see-`hd-self-screenshot-windows`. On macOS it's `screencapture`/CoreGraphics + CDP+windows) and **`BitBlt`** — are the Windows self-screenshot mechanics;. On macOS it's `screencapture`/CoreGraphics + CDP `Page.captureScreenshot`, with `dom.measure`-driven cropping for selectors.
skills/hydrogen-setup-steps/SKILL.md+1−1@@ -10,7 +10,7 @@ Machine-runtime version (default). The legacy 24-step Docker cascade When you first launched Adom Hydrogen (or after a virgin reset), Hydrogen ran a 18-step install sequence to turn a blank workspace into a fully-tooled Adom workspace — the `Adom-Workspace` machine. The heavy tooling (code-server, the 8 Adom CLIs, the claude CLI + Code extension, VS Code settings, and all `hd-*` skills) is already BAKED into the golden image; setup just imports that image, injects your Adom session, wires up the relay, and walks the Claude auth gate. This skill explains what each step did so you can help the user understand their environment, re-run failed steps, or wipe and rebuild. See `hydrogen-golden-image` for the baked-image model. -The cascade is executed by `setup_steps_macos.rs` (`step_defs_machine()` / `run_all_machine()`). `run_all_machine` is halt-on-failure, resume-not-restart, with per-step 3× auto-retry. In-machine work runs via `limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash -lc '<cmd>'` (the machine's DEFAULT user is `adom`, UID 1001, home `/home/adom`; under systemd-nspawn there's no wsl.conf — the default user comes from the machine config / nsenter `-S 1001 -G 1001`; root variant drops `-S 1001 -G 1001`). There is NO `docker exec` and NO Docker image anywhere in this flow.+The cascade is executed by `setup_steps_macos.rs` (`step_defs_machine()` / `run_all_machine()`). `run_all_machine` is halt-on-failure, resume-not-restart, with per-step 3× auto-retry. In-machine work runs via `limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash -lc '<cmd>'` (the machine's DEFAULT user is `adom`, UID 1001, home `/home/adom`; under systemd-nspawn the default user comes from the machine config / nsenter `-S 1001 -G 1001`; root variant drops `-S 1001 -G 1001`). There is NO `docker exec` and NO Docker image anywhere in this flow. ## The 18 steps (in order)
skills/hydrogen-setup/SKILL.md+2−2@@ -153,8 +153,8 @@ from the full pre-baked golden image `adom-golden.tar.gz` (pulled from the Docker image), creates the `adom` user, starts code-server, and verifies code-server reachable from the Mac on port 7380. This single step replaces the old Docker pull-image / create-container / start-container trio. The machine's-DEFAULT user is `adom` (UID 1001; under systemd-nspawn there's no wsl.conf — the-default user comes from the machine config / nsenter `-S 1001 -G 1001`), NOT root;+DEFAULT user is `adom` (UID 1001; under systemd-nspawn the default user comes from+the machine config / nsenter `-S 1001 -G 1001`), NOT root; in-machine exec = `limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash -lc '<cmd>'` (root variant drops `-S 1001 -G 1001`) — NEVER `docker exec`.
skills/hydrogen-ui-mac/SKILL.md+14−19@@ -7,8 +7,7 @@ description: > macOS-specific: Hydrogen'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 Hydrogen UI macos,+ (e.g. dom.measure resolves a selector's rect WITHOUT CDP). Trigger words — drive Hydrogen UI macos, WKWebView, no CDP, dom.measure, hd-ui-command, invoke_ui_action, ui/invoke macos, click Hydrogen menu mac, open dialog mac. ---@@ -23,9 +22,9 @@ covers what changes on a Mac: **how clicks reach the webview when there is no CD ## The macOS reality — WKWebView has no CDP On macOS Hydrogen'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+port**. Selector-based CDP `.click()` driving therefore does not work here — there is 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 Hydrogen's UI. For an element that isn't on the bus yet, **register it** (a 2-line `registerUiAction(...)` — see hydrogen-ui) rather than reaching for a selector click; there is nothing to click *through*.@@ -37,24 +36,20 @@ CDP. The backend (`src-tauri/crates/hd-control/src/lib.rs`, `invoke_ui_action`) 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.+identical round-trip on every host — but on macOS it's load-bearing, since there is no+CDP alternative. ## `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,+Geometry needed its own plumbing. WKWebView cannot crop a region screenshot+server-side via CDP `Page.captureScreenshot` with a clip — 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.+viewport:{width,height}}` in CSS px. It's a normal bus action — the bus's answer to+"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.+On macOS there is no CDP machinery at all: drive everything through the command bus+(`/ui/actions` → `/ui/invoke`) and register anything that's missing.
skills/hydrogen-volume/SKILL.md+3−6@@ -52,7 +52,7 @@ When you open Virgin Reset (Hydrogen setup panel), the checkbox toggles control ## Accessing workspace files from the Mac -There is **no Finder share** into the machine (no macOS equivalent of the old `\\wsl$` Explorer share). Reach your files via the relay or by shelling into the Lima VM.+There is **no Finder share** into the machine. Reach your files via the relay or by shelling into the Lima VM. ### 1. `limactl shell hd-builder` + nsenter + cp ```bash@@ -62,10 +62,7 @@ limactl shell hd-builder -- sudo nsenter -t <leader> -a -S 1001 -G 1001 -- bash ``` Use `limactl copy` to move files between the Mac and the VM disk, then `nsenter` + `cp` to land them in the machine's `/home/adom/project`. -### 2. From inside the machine, there is no `/mnt/c` drive mount-N/A on macOS — there are no Windows drive mounts. Use the relay instead (see below).--### 3. `adom-desktop send_files` / `pull_file` (from inside the workspace, via the relay)+### 2. `adom-desktop send_files` / `pull_file` (from inside the workspace, via the relay) ```bash # Send a workspace file to your Mac desktop's Downloads folder adom-desktop send_files '{"filePaths":["/home/adom/project/myfile.txt"],"targetApp":"general","destinationFolder":"."}'@@ -74,7 +71,7 @@ adom-desktop send_files '{"filePaths":["/home/adom/project/myfile.txt"],"targetA adom-desktop pull_file '{"filePaths":["/Users/<you>/Downloads/myfile.txt"],"saveTo":"/tmp"}' ``` -### 4. Open the workspace's `/home/adom/project/` in VS Code's File Explorer+### 3. Open the workspace's `/home/adom/project/` in VS Code's File Explorer Just use the built-in code-server tree — the project folder is what's open, so anything you create/edit there hits the machine fs directly. ## Backing up your workspace