← Commit history
package.json+1−1
@@ -4,7 +4,7 @@   "type": "bootstrap",   "title": "Adom Hydrogen (platform base)",   "brief": "Layer Hydrogen's workspace onto a standard Adom workstation.",-  "version": "0.3.10",+  "version": "0.3.11",   "description": "Hydrogen's PLATFORM-GENERIC workspace layer on top of adom/core. Installs adom/core for the full Adom ecosystem, then adds everything common to running inside Hydrogen on ANY platform: the runtime-neutral hydrogen-* skills and the generic editor configuration (Claude Code CLI + extension, VS Code settings, trusted domains). Platform-specific layers depend on THIS: adom/hydrogen-windows-bootstrap (WSL2), adom/hydrogen-mac-bootstrap, adom/hydrogen-ubuntu-bootstrap. The reference design other orgs copy to build their own bootstrap on adom/core.",   "org": "adom",   "platform": "any",
page.json+1−1
@@ -4,7 +4,7 @@   "type": "bootstrap",   "title": "Adom Hydrogen (platform base)",   "brief": "Layer Hydrogen's workspace onto a standard Adom workstation.",-  "version": "0.3.10",+  "version": "0.3.11",   "description": "Hydrogen's PLATFORM-GENERIC workspace layer on top of adom/core. Installs adom/core for the full Adom ecosystem, then adds everything common to running inside Hydrogen on ANY platform: the runtime-neutral hydrogen-* skills and the generic editor configuration (Claude Code CLI + extension, VS Code settings, trusted domains). Platform-specific layers depend on THIS: adom/hydrogen-windows-bootstrap (WSL2), adom/hydrogen-mac-bootstrap, adom/hydrogen-ubuntu-bootstrap. The reference design other orgs copy to build their own bootstrap on adom/core.",   "org": "adom",   "tags": [
skills/hydrogen-adom-bridge/SKILL.mdadded+233
@@ -0,0 +1,233 @@+---+name: hydrogen-adom-bridge+description: >+  What Hydrogen (ah) and Adom Bridge (ab) are, what each does, and how+  they work together — so the AI in the workspace knows it has HANDS on the+  user's real operating system. Hydrogen is the workspace app the user looks at; ab is+  the bridge that reaches the user's actual Windows machine (macOS/Linux coming+  soon) to create files & folders, run shell commands, take OS screenshots,+  launch apps, open browsers (Pup / native), and drive KiCad / Fusion 360. Hydrogen+  bundles ab during install and runs it in embedded mode, but ab is a standalone+  product that ALSO connects Adom cloud containers to a user's machine. Hydrogen also+  has a BUILT-IN desktop bridge of its own that serves a subset of ab's verbs.+  READ THIS to understand your reach beyond the workspace and how to invoke it.+  Trigger words — adom desktop, ab, ad cli, what can you do on my computer, reach+  my machine, create a file on my pc, make a folder on my desktop, run a command+  on my machine, control the host, host screenshot, screenshot my screen, os+  screenshot, open a file on my computer, control my desktop, bridge to my pc,+  send file to my desktop, pull file from my desktop, hd and ad, two apps, how+  do hd and ad work together, talk to hydrogen desktop, desktop bridge, relay,+  embedded mode, ab hidden, hd_status, hd_api, shell_execute, adom-bridge-cli ping,+  adom-bridge-cli status.+---++# Hydrogen ↔ Adom Bridge — your reach onto the user's real machine++You (the AI) run inside the **Hydrogen workspace** (a WSL2 Ubuntu distro by default).+That's a sandbox. **Adom Bridge (ab) is how you reach OUT of it onto the user's+actual operating system** — their real files, shell, screen, and desktop apps.+Knowing ab exists is the difference between "I can only work in here" and "I can+create that file on your Desktop, screenshot your screen, and open it in KiCad."++> **Platform reality (2026-06-12):** ab reaches the user's real **Windows**+> machine. macOS and Linux are *coming soon* — Hydrogen's host layer (screenshots,+> notifications, captions, window control) is currently Windows-only. Don't+> promise file/shell/screenshot actions on a Mac or Linux box yet.++## Two apps, two jobs++| | **Hydrogen (ah)** | **Adom Bridge (ab)** |+|---|---|---|+| What it is | The user-facing workspace app (Tauri). VS Code pane + Wiki + the runtime that hosts your workspace. | A bridge app that talks to the user's real OS and local apps. |+| What the user sees | The window they work in. | Usually nothing — Hydrogen hides it (embedded mode). |+| What it does for YOU | Hosts you, your editor, your tools. | Lets you act on the host: files, folders, shell, OS screenshots, app launch, KiCad/Fusion, browsers. |+| Runs without the other? | Hydrogen spawns ab. | **Yes** — ab is a standalone product; it also connects Adom *cloud* containers to a user's machine. |++**Why two apps:** ab came first and is genuinely powerful — it's what lets any+Adom cloud container reach into a user's desktop. Rather than reinvent it, Hydrogen+**bundles ab and makes it part of Hydrogen's install**, then puts it in *embedded mode*+so the user only ever manages one app (ah). The two talk to each other+constantly. See [hydrogen-embedded-ad](../hydrogen-embedded-ad/SKILL.md) for the embedding+mechanics (tray ownership, lifecycle, standalone↔embedded transitions).++## Hydrogen's built-in bridge vs the embedded ab (dual-client)++Here's the subtlety that matters when you reason about "who serves this verb?":+**there are two desktop clients on the host, not one.**++1. **Hydrogen's own built-in bridge** — Hydrogen's `hydrogen-app` crate implements a desktop bridge+   *itself* (`commands.rs::handle_command` → `screenshot.rs::handle_desktop_command`).+   It serves a **subset** of ab's verbs directly inside Hydrogen's process:+   `list_windows, screenshot_window, screenshot_screen, open_folder, open_url,+   bring_to_front, set_window_state, list_files, watch_files, install_kicad,+   install_node, list_browsers` under the `desktop` app, plus the top-level apps+   `caption, notify, shell, kicad, fusion360, browser` and the desktop verbs+   `set_project_watch, trigger_project_watch, revoke_approvals`.+2. **The standalone ab, spawned `--embedded`** by Hydrogen's supervisor+   (`ad_supervisor.rs`). ab serves the **full** verb surface — including ones+   Hydrogen's built-in bridge does NOT implement:+   `desktop_record_*`, `desktop_recorder_*`, `desktop_list_monitors`,+   `desktop_pull_glob`, `desktop_embedded_*`.++Both ends sit behind the same `adom-bridge-cli` relay, so from the CLI you don't+choose between them — the relay routes to whichever client is connected. But+"will this verb work right now?" depends on which client is up. **Don't assume a+verb exists — verify capability first:**++```bash+adom-bridge-cli status   # → .capabilities lists what the connected client(s) can do+```++If `.capabilities` is missing `record` (or `desktop_list_monitors` errors with+"unknown desktop command"), the embedded ab isn't connected — only Hydrogen's built-in+bridge is — so recording / multi-monitor / glob-pull aren't available until ab+is up. Screenshots, window control, files, shell, captions, notifications and+the KiCad/Fusion/browser bridges all work off Hydrogen's built-in bridge regardless.++## What ab/Hydrogen let you do on the user's real Windows machine++All via the `adom-bridge-cli` CLI from inside the workspace. Rather than+re-document every verb here, this is a **capability map → the focused skill**:++| Capability | Verb(s) / surface | Where it's documented |+|---|---|---|+| **Create files/folders on the host** | `send_files` (container → desktop) | [hydrogen-file-transfer](../hydrogen-file-transfer/SKILL.md) |+| **Pull files from the host** | `pull_file` (desktop → container, SHA256-verified); browse + watch via `list_files` / `watch_files` | [hydrogen-file-transfer](../hydrogen-file-transfer/SKILL.md) |+| **Run a shell command on the host** | `shell_execute` (real PowerShell/shell) | shell-trust model below |+| **Screen/window control + screenshots** | `desktop_screenshot_screen` / `desktop_screenshot_window` / `desktop_list_windows`, `desktop_set_window_state`, `desktop_bring_to_front` | [hydrogen-self-screenshot](../hydrogen-self-screenshot/SKILL.md) |+| **Record the screen / a tab** | `desktop_record_*` (whole screen), `browser_record_*` (one tab) | [hydrogen-recording](../hydrogen-recording/SKILL.md) — ab-served, verify `record` capability |+| **Desktop notifications** | `notify_user` (title/body/level + action buttons) | [hydrogen-notifications](../hydrogen-notifications/SKILL.md) |+| **On-screen captions** | `caption` (always-on-top click-through overlay) | [hydrogen-captions](../hydrogen-captions/SKILL.md) |+| **Open browsers** | `browser_*` (Pup) and the Browser Picker | [hydrogen-open-url](../hydrogen-open-url/SKILL.md), `pup` |+| **Drive KiCad / Fusion 360 / Pup** | `kicad_*`, `fusion_*`, `browser_*` | [hydrogen-bridges](../hydrogen-bridges/SKILL.md) |+| **Embedded mechanics (tray/lifecycle)** | `desktop_embedded_*` | [hydrogen-embedded-ad](../hydrogen-embedded-ad/SKILL.md) — ab-served |++For the complete verb list run `adom-bridge-cli list_commands` (or see the+`adom-bridge-cli` skill).++### Host shell-trust model++`shell_execute` runs a **real command on the user's machine** (`cmd /C` on+Windows). In **embedded mode Hydrogen auto-approves** shell commands so the AI isn't+blocked on per-command approval dialogs — convenient, but it means anything you+run there really runs. Revoke the standing auto-approval at any time:++```bash+adom-bridge-cli shell_auto_approve '{"duration_secs":0}'   # turn auto-approve off now+```++When you *don't* need a free-form shell, prefer the **no-escape structured+runners** over hand-quoted `shell_execute` (ab ≥ 1.8.50):+`adom-bridge-cli run_script '{"interpreter":"bash|cmd|powershell","scriptB64":"<b64>"}'`+and `adom-bridge-cli wsl_exec '{"distro":"Adom-Workspace","user":"adom","scriptB64":"<b64>"}'`+— base64 the script so no quoting survives to be mangled.++### Auto-installing missing apps (winget)++If KiCad or Node.js is missing on the host, you don't have to stop at a download+link — trigger an unattended winget install:++```bash+adom-bridge-cli desktop_install_kicad '{}'   # winget install KiCad+adom-bridge-cli desktop_install_node  '{}'   # winget install Node.js (unblocks the Pup bridge)+```++(`install_kicad` fires when `kicad_list_versions` returns+`errorCode:"kicad_not_installed"`; `install_node` when a `browser_*` call returns+`errorCode:"node_not_found"`.)++### KiCad project auto-sync++`set_project_watch` / `trigger_project_watch` keep a KiCad project mirrored+between the workspace and the host. The watcher fires on changes to+`.kicad_sch` / `.kicad_pcb` / `.kicad_pro` files+(`project_watch.rs::KICAD_EXTENSIONS = ["kicad_sch", "kicad_pcb", "kicad_pro"]`),+so edits you make in the workspace land on the user's machine (and vice-versa)+without manual `send_files`/`pull_file` round-trips.++## Talking to Hydrogen + ab from the CLI++You reach the host through the **`adom-bridge-cli` CLI**, which relays your commands+over a WebSocket to the desktop client(s).++**Host shell + files:**+```bash+adom-bridge-cli shell_execute '{"command":"<cmd>","timeoutSeconds":60}'+adom-bridge-cli pull_file  '{"filePaths":["C:\\path\\file"],"saveTo":"/tmp"}'+adom-bridge-cli send_files '{"filePaths":["/tmp/x"],"saveTo":"C:\\Users\\<you>"}'+adom-bridge-cli desktop_list_windows+```++**Hydrogen control (the Hydrogen app itself):**+```bash+adom-bridge-cli hd_status            # is Hydrogen running + composed runtime state+adom-bridge-cli hd_screenshot        # window-bounded Hydrogen shot (resize <1500px before reading!)+adom-bridge-cli hd_log               # tail Hydrogen's log+adom-bridge-cli hd_launch            # start Hydrogen detached+# Direct Hydrogen control API (HTTP, no shell-escaping pain):+adom-bridge-cli hd_api '{"method":"POST","path":"/setup/run-all","body":{}}'+adom-bridge-cli hd_api '{"method":"GET","path":"/health"}'+```+`hd_api` hits Hydrogen's **control API**, discovering its real port from+`%APPDATA%\hydrogen-desktop\ports.json` key `control` (fallback **47084**).++**Embedded-mode introspection (ab-served):**+```bash+adom-bridge-cli desktop_embedded_status   # embedded=true/false, enteredVia=launch-flag|runtime-adopt+```++## How the connection works (and how you check it)++```+You (AI in the workspace)+  └─ adom-bridge-cli <verb> '<json>'        ← CLI in the distro+       └─ relay  (adom-bridge-cli serve: WS :8765 + HTTP :8766, started in the workspace)+            └─ WebSocket ──► Hydrogen's built-in bridge AND/OR the embedded ab on the user's Windows machine+                 └─ acts on the OS / KiCad / Fusion / Chrome+```++- In Hydrogen the relay is started for you by the **`start-relay`** setup step; Hydrogen's+  built-in bridge and the embedded ab both connect to it. Under WSL2 the relay+  binds `0.0.0.0:8765` in the distro and WSL2 forwards it to the host's+  `localhost:8765` (HTTP on `8766`), which is how the host-side clients reach+  your in-workspace relay (see the `hydrogen-networking` skill). It's reached+  **same-port** under WSL2 — there's no host 47081/47082 remap.+- **Always verify the bridge before acting on the host:**+  ```bash+  adom-bridge-cli ping       # → {"status":"connected", ...} means a client is reachable+  adom-bridge-cli status     # who's connected + .capabilities + which local apps are installed/running+  ```+  If `ping` fails, no desktop client is connected — tell the user, and (if needed)+  walk the `adom-bridge-cli` setup steps. Don't claim you acted on their machine+  without a successful round-trip. Don't try to "fix" a dead host client from in+  here — surface it.++## What NOT to do++- **Never `taskkill /F /IM adom-bridge.exe`** — the host ab is your relay bridge;+  killing it severs your control channel (you can't get it back from in here).+- **Never hardcode `:9001` as Hydrogen's control API.** `9001` is real — it's ab's+  liveness beacon that ab probes to detect Hydrogen — but Hydrogen's actual control API is+  **47084** (use `hd_api`, which reads `ports.json` → `control`).+- **Don't broad-kill `node`** — VS Code Server runs as node; killing it kills the+  whole workspace.+- Resize screenshots to `<1500px` before reading them, and inject every screenshot+  into shotlog with a real description.++## Mental model for answering the user++When the user asks for something that lives on their real computer — "save this+to my Desktop", "what's on my screen", "open this in KiCad", "run this command on+my machine" — that's an **ab** job, and you can do it. When it's about the+workspace itself (editor, files under `/home/adom/project`, the runtime), that's+**Hydrogen**. Lead with what you can do, verify with `adom-bridge-cli ping`, then act.++## Related skills+- [hydrogen-embedded-ad](../hydrogen-embedded-ad/SKILL.md) — how Hydrogen installs + embeds ab (tray, lifecycle, standalone↔embedded)+- [hydrogen-bridges](../hydrogen-bridges/SKILL.md) — the KiCad / Fusion / Puppeteer bridge ecosystem+- [hydrogen-file-transfer](../hydrogen-file-transfer/SKILL.md) — send/pull files, browse + watch the host filesystem+- [hydrogen-self-screenshot](../hydrogen-self-screenshot/SKILL.md) — host screenshots + window control+- [hydrogen-recording](../hydrogen-recording/SKILL.md) — screen vs tab recording (ab-served)+- [hydrogen-notifications](../hydrogen-notifications/SKILL.md) — desktop toasts; [hydrogen-captions](../hydrogen-captions/SKILL.md) — on-screen caption overlay+- [hydrogen-open-url](../hydrogen-open-url/SKILL.md) — the ways to open a URL (Pup, native browser, picker, …)+- `pup` — driving Pup browser windows; `adom-bridge-cli` — the full CLI verb reference
skills/hydrogen-doctor/SKILL.mdadded+82
@@ -0,0 +1,82 @@+---+name: hydrogen-doctor+description: >+  The Hydrogen Doctor: a one-click full health scan of the whole stack+  (workspace, code-server, Claude, Adom auth, ports, relay, Adom Bridge) with a+  safe one-click fix. Lives in the Adom menu ("Doctor...") and on the control+  API (GET/POST /doctor). Read this when the user says something is broken and+  they don't know what, after a laptop sleep left things weird, when chat or the+  editor went dark, or when you want a machine-readable health snapshot before+  and after a repair. Trigger words: doctor, health check, diagnose, diagnostics,+  something is broken, everything is broken, nothing works, run the doctor,+  fix problems, still failing, workspace restart, /doctor.+---++# Hydrogen Doctor: diagnose and repair the whole stack in one place++The Doctor answers "is everything actually working?" with evidence, then fixes+what it safely can. It runs ~17 real checks end to end (not "is the process+alive" but "does it answer correctly"), shows each result with a plain-English+explanation, and offers two levels of repair.++## Where it lives++- **UI**: Adom menu (top-left) → **Doctor...**. A dialog lists every check with+  a green/red state; hovering a row reveals a paragraph explaining what that+  check means and why it matters. Buttons: **Re-run checks**, **Fix problems**,+  and (only when recommended) **Restart workspace**.+- **API** (Hydrogen control API, see `hydrogen-api` for the port):+  - `GET /doctor` runs all checks, returns `{checks, ...}` with per-check+    `ok/message`.+  - `POST /doctor` body `{"fix": true}` runs checks, applies the safe fix,+    re-runs checks, and returns+    `{before, after, actions, still_failing, recommend_workspace_restart}`.++## What it checks (the 17 checks)++Workspace side: the WSL2 `Adom-Workspace` distro is present and running+(`workspace`), the Adom API key exists (`api-key`), required env vars are+exported (`env-vars`), `adom-cli` is installed (`adom-cli`) and can actually+reach Adom's cloud (`adom-cli-api`), skills are deployed (`skills`), the+in-container relay answers on 8765/8766 (`relay`).++Editor side: code-server is genuinely serving (`code-server`, the big one after+sleep), the required extensions are installed (`extensions`), Claude Code CLI is+installed (`claude-installed`) and signed in (`claude-auth`), the live SSE link+between editor and app is up (`sse`), the workspace-layout API responds+(`webview`).++Plumbing: workspace service ports reachable from Windows (`ports`), identity+established via api-key + session (`identity`, the legacy adom-identity.json is+NOT required), Adom Bridge reachable (`adom-desktop`), and `port-integrity` (a+post-sleep check: code-server must be serving; a control API that moved off+47084 to an ephemeral port is fine and reported as a note, because everything+reads live ports from ports.json).++## The two repair levels++1. **Fix problems** (safe, no confirmation needed): runs the same heal cascade+   the wake repair uses (see `hydrogen-wake-repair`), waits for code-server's+   /healthz, then re-runs every check so you can see before vs after. It never+   drops the user's editor session unless the session was already dead.+2. **Restart workspace** (disruptive, confirm-gated): only offered when the fix+   pass leaves failures and the Doctor sets `recommend_workspace_restart`. It+   calls `POST /container-restart`, which reloads VS Code and Claude (~30s+   outage). Never trigger this without the user's OK.++## How you (the AI) should use it++- User says "nothing works" or "it froze after I opened my laptop": call+  `GET /doctor` first and READ the failures instead of guessing.+- To repair: `POST /doctor {"fix": true}`, then report `actions` taken and any+  `still_failing` checks. If `recommend_workspace_restart` is true, ask the+  user before restarting.+- After any repair, re-run `GET /doctor` and only claim health you can see+  (all `ok: true`).++## Related skills++- `hydrogen-wake-repair`: the automatic version of the fix that runs on laptop+  wake, plus the wake indicator and the manual "Run Wake Check" menu item.+- `hydrogen-workspace-lifecycle`: what a workspace restart actually does.+- `hydrogen-api`: how to find the control port.
skills/hydrogen-ports/SKILL.mdadded+259
@@ -0,0 +1,259 @@+---+name: hydrogen-ports+description: How Hydrogen does port forwarding between your WSL2 workspace and your Windows machine — WSL2's automatic `0.0.0.0` localhost-forwarding (no port map to declare), the code-server `/proxy/<port>/` URL pattern that exposes any internal port, the port-forward registry for `127.0.0.1`-only services that WSL2 won't auto-forward, and the PortMappingsDialog UI. Use when the user asks "why isn't my server reachable", "how do I expose port X", "what's localhost:7380", "register a port", "auto-forward a port", or "the dynamic port dialog". Trigger words — port forwarding, ports, hd ports, container port, proxy port, code-server proxy, /proxy/, port mappings dialog, port hints, auto forward, expose port, register port, host port, dynamic port, ports.json, PortConfig, port resolver, localhost port not working.+---++# Hydrogen Ports — forwarding workspace services to your Windows host++The Hydrogen workspace is the WSL2 distro `Adom-Workspace`.+There is **no port mapping to declare** — WSL2 auto-forwards listeners for you.+Any service that binds `0.0.0.0:<port>` inside the distro is reachable at+`localhost:<sameport>` on Windows automatically. code-server itself binds+`0.0.0.0:7380`, so `localhost:7380` on Windows just works. For browser-facing+HTTP/WS, code-server's `/proxy/<port>/` URL pattern is still preferred and still+exposes any internal port. For the cases WSL2 auto-forward can't cover+(`127.0.0.1`-only listeners, or when auto-forward is flaky), Hydrogen's port-forward+registry creates a real host-side proxy on demand.++## The first rule: bind `0.0.0.0`++| Bind address inside distro | Reachable on Windows? |+|----------------------------|------------------------|+| `0.0.0.0:N` (all interfaces) | YES — `localhost:N` automatically |+| `127.0.0.1:N` (loopback only) | NO — WSL2 won't forward it |++So before you do anything else: **make your service bind `0.0.0.0`.** For most+dev servers that's a flag (`--host 0.0.0.0`, `vite --host`, `HOST=0.0.0.0`,+`server.address("0.0.0.0")`). Once it binds `0.0.0.0`, it auto-forwards — no+registration needed.++## The code-server proxy URL pattern++Any service listening on port N inside the distro is reachable at:++```+http://localhost:7380/proxy/N/+```++This works for HTTP services. WebSockets work too (`ws://localhost:7380/proxy/N/`).+No port mapping needed, and it works for `0.0.0.0` AND `127.0.0.1`-bound+services (code-server is inside the distro, so it reaches loopback listeners+that Windows can't). This is the preferred path for anything you open in a+browser.++Examples:+- Your dev server on port 5173 → `http://localhost:7380/proxy/5173/`+- The relay HTTP server on port 8766 → `http://localhost:7380/proxy/8766/`+- adom-vscode's API on port 8821 → `http://localhost:7380/proxy/8821/`++**This is how everything-inside-the-distro reaches everything-outside.** Inside+the distro, services that need to talk to "the host" use `127.0.0.1:<port>` —+WSL2 mirrored networking shares loopback with the Windows host — for Hydrogen's own+services (Hydrogen's live control URL is in `~/.adom/hydrogen-control-url`), and the proxy+URL for everything else.++## The port-forward registry (for what auto-forward can't cover)++Auto-forward handles the common case. You still need the registry — Hydrogen's+port-forward registry, serviced by the port-watcher daemon (see+`hydrogen-port-watcher`) — when:++- The service binds **`127.0.0.1` only** and you can't change it (some OAuth+  callback servers, some native tools). WSL2 won't auto-forward loopback-only+  listeners; the registry creates a real host proxy that reaches them through+  code-server.+- WSL2 localhost-forwarding is **lagging or broken** for a port (a real Hydrogen+  failure mode: "code-server alive in distro but Windows can't reach+  127.0.0.1:7380"). The registry gives a reliable host-side proxy that doesn't+  depend on WSL2's forwarder.++Decision order:+1. **Bind `0.0.0.0`** → auto-forwarded, done.+2. Can't bind `0.0.0.0` (loopback-only), or auto-forward is unreliable →+   **register the port** so Hydrogen proxies it.++### Register a port (from inside your workspace)++```bash+# Tell Hydrogen: "please bind localhost:5555 on Windows and forward into the distro"+adom-cli port-forward register 5555 --name "oauth-cb" --reason "127.0.0.1-only oauth callback" --visibility external+```++Visibility options:+- `external` — bind `localhost:5555` on Windows via an Hydrogen-managed proxy AND+  keep the `/proxy/` URL working. Best for OAuth callbacks, native clients,+  loopback-only servers.+- `internal` — proxy URL only, no host binding. Best for webview panels that+  don't need a separate host port.+- `either` — let Hydrogen decide based on heuristics (defaults to external).++### Unregister+```bash+adom-cli port-forward unregister 5555+```++### List+```bash+adom-cli port-forward list+```++## The Port Mappings dialog++Open via: Hydrogen Adom menu → "Port Mappings", or `POST http://127.0.0.1:47084/setup/panel/show`+then navigate to the Ports tab. Shows:++- **Auto-forwarded ports** — `0.0.0.0` listeners WSL2 is mirroring to Windows+- **Registered ports** — anything you've registered via `port-forward register`+  (Hydrogen-managed host proxies, for loopback-only / unreliable cases)++Each row shows the direct URL (`http://localhost:<port>`) AND the proxy URL+(`http://localhost:7380/proxy/<port>/`). Click either to open in your browser+via the Browser Picker.++## Hydrogen's host-side port registry++Hydrogen reads/writes its host-side port assignments at+`%APPDATA%\hydrogen-desktop\ports.json`. The `PortConfig` struct+(`hydrogen-control/src/ports.rs`) holds exactly four service ports —+`code_server`, `proxy`, `control`, `cdp` — plus the bind `hostname`. There are+no relay-WS / relay-HTTP host ports in `PortConfig`: under WSL2 the relay binds+**8765 (WS) / 8766 (HTTP) inside the distro**, reached at the same port on+Windows (mirrored loopback) or via `/proxy/8766/`, and discovered from+`~/.adom/cli-relay-ports.json` inside the distro. There is no host 47081/47082+listener.++Defaults (you can override via ports.json):++| Service | Default host port |+|---------|-------------------|+| code-server | 7380 |+| Discovery server | 47080 |+| Reverse proxy (`proxy`) | 47083 |+| Hydrogen control API (`control`) | 47084 |+| WebView2 CDP (`cdp`) | 47085 |+| KiCad bridge | **dynamic** (adom-bridge-cli picks at bridge launch) |+| Fusion bridge | **dynamic** (adom-bridge-cli picks at bridge launch) |+| Puppeteer bridge | **dynamic** (adom-bridge-cli picks at bridge launch) |++**Conflict resolution is NOT "next sequential port."** On startup+`PortConfig::resolve_available()` checks `proxy`, `control`, and `cdp`; if a+preferred fixed port is taken, Hydrogen binds an **ephemeral `127.0.0.1:0`** port (the+OS hands back a guaranteed-free one outside any HNS reservation) and persists it+to `ports.json`. It does **not** walk to 47086, 47087, … — HNS reserves+contiguous chunks invisible to netstat, so a walk would march into the next+reserved block. `code_server` is **exempt** and never resolved (it's tied to the+distro's mirrored port). So a busy box does NOT predictably land on+47083/47085 — the AI must discover the live ports.++**Never hardcode `127.0.0.1:9001` in distro code** — that was the old default+and has since moved. To find the real runtime ports, hit **`GET /ports`** on the+control API (default `127.0.0.1:47084`) — it returns+`{code_server, proxy, control, cdp, hostname}` straight from the resolved+`PortConfig` (`hydrogen-app/src/lib.rs` `get_ports`). `ports.json` is the single source+of truth every consumer reads.++## Discovering Hydrogen itself: the three-rung ladder++Because `control`/`proxy`/`cdp` can rebind to ephemeral ports, anything that+needs to FIND a running Hydrogen walks this ladder (static defaults are only+rung zero, never an assumption):++1. **Local files (authoritative when present).**+   - Windows side: `%APPDATA%\hydrogen-desktop\ports.json` (written every+     launch by `resolve_available()`).+   - Inside the distro: `~/.adom/hydrogen-control-url` (full live control URL)+     and `~/.adom/hydrogen-ports.json` (all four ports), both stamped by+     Hydrogen into the workspace. Adom Bridge's own direct API is at+     `~/.adom/direct-api-port` (default 47200) and the relay at+     `~/.adom/cli-relay-ports.json` (8765 WS / 8766 HTTP).+2. **Verify liveness AND identity.** A port answering `/health` is not proof+   it is THIS install: a zombie from an uninstalled copy can still be serving+   (a real observed failure). `GET /buildinfo` returns `instance_id`, `pid`,+   and `install_path`; check they match what you expect before trusting a+   discovered port.+3. **Cloud KV (works even when local files are unreachable).** On every+   launch, and every 4 hours after, Hydrogen publishes its live runtime+   identity to the Adom cloud KV (Carbon):++   - Key: `desktop.runtime.<machine>.hydrogen` (machine = lowercase+     `COMPUTERNAME`, sanitized to `[a-z0-9_]`).+   - Value: a JSON string:+     `{host, control, proxy, cdp, code_server, instance_id, pid, install_path, version, ts}`.+   - Read it: `GET https://carbon.adom.inc/user` (session token or API key+     auth) then `body.hydrogen_preferences.settings["desktop.runtime.<machine>.hydrogen"]`.+   - Freshness: compare `ts` (unix seconds) to now; the heartbeat refreshes it+     every 4 hours, so a `ts` older than ~5 hours means that instance is+     probably gone. Always confirm by hitting `/buildinfo` on the advertised+     port and matching `instance_id`.++   Adom Bridge publishes its container connection the same way+   (`desktop.container.<id>`). This is what lets a cloud container, another+   machine, or a fresh install find the user's running desktop apps without+   port scanning.++## Inside vs outside — which URL to use++| You're calling from | To reach a service on port N | Use |+|---------------------|------------------------------|-----|+| Distro shell / app | Another distro service | `http://localhost:N` |+| Distro app | The Windows host | `http://127.0.0.1:N` (WSL2 mirrored networking shares loopback with the host — no gateway IP, no firewall rule) |+| Windows browser | A `0.0.0.0`-bound distro service | `http://localhost:N` (auto-forwarded) |+| Windows browser | Any distro service (HTTP/WS) | `http://localhost:7380/proxy/N/` (proxy URL, preferred) |+| Windows browser | A `127.0.0.1`-only distro service | `http://localhost:N` (only after `port-forward register ... external`) |+| Distro | Hydrogen's own control API (on Windows host) | `$(cat ~/.adom/hydrogen-control-url)` → `http://127.0.0.1:<dynamic>` (port is dynamic per launch) |++## Common bugs++**"My dev server at port 5173 doesn't load in Chrome"**+- Most likely it's bound `127.0.0.1` only. Restart it bound to `0.0.0.0`+  (e.g. `vite --host`) and it auto-forwards to `localhost:5173`.+- OR use the proxy URL: `http://localhost:7380/proxy/5173/`.+- If it IS on `0.0.0.0` but still unreachable, WSL2's forwarder may be lagging —+  register it: `adom-cli port-forward register 5173 --visibility external`.++**"OAuth callback fails with refused connection"**+- The provider is hitting `http://localhost:5555/callback` but the callback+  server is loopback-only inside the distro, so WSL2 doesn't forward it.+- Register first: `adom-cli port-forward register 5555 --visibility external --reason "oauth callback"`.+- Hydrogen auto-detects callback URLs and starts a proxy for them automatically in+  many cases (see Hydrogen log for `[oauth] Callback port X detected`), but+  registering explicitly is the reliable path.++**"`localhost:7380` shows nothing / code-server unreachable from Windows"**+- code-server is alive in the distro but WSL2 localhost-forwarding wedged (a+  real Hydrogen-logged failure mode). The port-forward registry / port-watcher+  daemon installs a host-side proxy to recover this — see `hydrogen-port-watcher`.+  Or restart Hydrogen to re-establish the forward.++## Related skills++- `hydrogen-networking` — the broader picture: `0.0.0.0` auto-forward, hostnames,+  proxy architecture, relay vs direct connect, firewall rules, NEVER do these+- `hydrogen-port-watcher` — the retained daemon that registers `127.0.0.1`-only+  listeners and covers WSL2 auto-forward gaps+- `hydrogen-container` — what's inside the workspace reachable on which port+- `hydrogen-desktop-sse` — the workspace API which runs on these ports+- `hydrogen-browser-picker` — what happens when you click a port-mappings URL++## Bridge ports are dynamic++KiCad, Fusion 360, Puppeteer, and any 3rd-party bridges no longer have known+fixed ports. When a bridge launches, **adom-bridge-cli picks an available port at+runtime** and registers it. To find a running bridge's current port, query+adom-bridge-cli:++```bash+adom-bridge-cli status+# Look at desktop.apps.<bridge>.bridgePort+```++Or use the bridge directly via adom-bridge-cli CLI — you don't need the port at all:++```bash+adom-bridge-cli kicad_open_board '{"path":"..."}'  # adom-bridge-cli routes to the right port+adom-bridge-cli browser_eval '{"js":"..."}'+```++This means **old code or skill examples that hardcoded fixed bridge ports+(8771 / 8773 / 8851) are stale.** Use the adom-bridge-cli CLI or `status` lookup+instead.
skills/hydrogen-self-update/SKILL.md+30−11
@@ -1,14 +1,22 @@ --- name: hydrogen-self-update-description: "How the AI keeps the Hydrogen APP itself (the desktop frontend, not the workspace) up to date — AI-first, consent-based. Use when asked \"is there an Hydrogen update\", \"update Hydrogen\", \"is my Hydrogen current\", \"what version of Hydrogen am I on\", \"update the app\", \"new Hydrogen version\". Trigger words: Hydrogen update, update hydrogen, app update, is Hydrogen current, Hydrogen version, new version of Hydrogen, relaunch to update, self-update."+description: "How the AI keeps the Hydrogen APP itself (the Windows/macOS frontend, not the workspace) up to date — AI-first, consent-based. Use when asked \"is there an Hydrogen update\", \"update Hydrogen\", \"is my Hydrogen current\", \"what version of Hydrogen am I on\", \"update the app\", \"new Hydrogen version\". Trigger words: Hydrogen update, update hydrogen desktop, app update, is Hydrogen current, Hydrogen version, new version of Hydrogen, relaunch to update, self-update." --- -# Hydrogen Self-Update — the AI updates the app for you (consent-based)+# Hydrogen Self-Update — the app updates itself (a banner + an AI path) -This is how the **Hydrogen app itself** (the desktop shell around your editor)-stays current. It is NOT the `workspace-updater` (that's the in-distro tooling). It's **AI-first**:-there is no nagging button — the AI notices a new Hydrogen version, tells you both version numbers, and-on your OK downloads + relaunches onto the new version.+This is how the **Hydrogen app itself** (the Windows/macOS shell around your editor)+stays current. It is NOT how the in-distro tooling/skills update (those converge registry-native+via `adom-wiki pkg update` + the `adom/hook` prompt hook). There are **two ways** a new Hydrogen version+gets applied, and they share one backend:++1. **The Restart-to-update banner (what the user sees).** When the updater supervisor+   (`updater.rs`) has silently downloaded + SHA-verified a newer version in the background, Hydrogen+   shows a top-of-app bar: **"Restart to update (vX → vY)"** (`UpdateBanner.svelte`). One click+   calls `updater_install` and relaunches onto the new version. If the user ignores it, the staged+   update auto-applies on the next launch anyway.+2. **The AI-first path (you).** You can also proactively notice a new version, tell the user both+   numbers, and on their OK apply it — same backend, no waiting for the banner.  ## When to check Check at the **start of a session** and whenever the user asks about updates. Don't poll@@ -16,8 +24,15 @@ constantly.  ## How to check (know both version numbers) ```-GET http://127.0.0.1:<control-port>/updater/status+POST http://127.0.0.1:<control-port>/updater/check   # refresh: re-poll version.json + stage now+GET  http://127.0.0.1:<control-port>/updater/status  # read the result ```+`POST /updater/check` is the same thing as the Settings window's "Check now"+button: it re-polls the wiki manifest immediately and starts the background+download/stage if a newer version exists. Fire it, wait a few seconds, then+read `/updater/status`. Without it you are reading the result of the last+periodic poll (startup + every 4 hours), which can be stale right after a+release ships. Returns `{ current_version, latest_version, update_available, staged, ... }`: - `update_available: true` → a newer Hydrogen exists. - `staged: true` → it's already downloaded + SHA-verified in the background, so applying is an@@ -42,9 +57,13 @@ few seconds — you can pick the conversation right back up. - **Consent-first.** Never relaunch Hydrogen without the user's OK (it restarts their app). Pick a   natural break — not mid-task. - **State both versions** (current → latest) so the user knows what's changing.-- This updates the **app shell only**. Editor extensions/code-server use the reload banner;-  in-workspace tooling/skills use the `workspace-updater`. Don't confuse the three.+- This updates the **app shell only**. Editor extensions/code-server use their own reload banner;+  in-workspace tooling/skills converge registry-native (`adom-wiki pkg update` via `adom/hook`).+  Don't confuse the three.  ## Resolving the control port-Read it from `VSCODE_PROXY_URI` / the Hydrogen `[ports]` log line (default control API `47084`), or-reach it through the relay/proxy like other Hydrogen control endpoints.+From inside the workspace, `cat ~/.adom/hydrogen-control-url` is the live URL+(the control port is 47084 by default but rebinds to an ephemeral port when+47084 is taken, so never hardcode it). See the discovery ladder in+`hydrogen-ports` (ports.json on Windows, `~/.adom/hydrogen-ports.json` in the+distro, and the cloud KV fallback).
skills/hydrogen-skill-catalog/SKILL.mdadded+109
@@ -0,0 +1,109 @@+---+name: hydrogen-skill-catalog+description: The catalog of skills available to your Claude inside this Hydrogen workspace. Lists every public `hd-*` skill that ships with Hydrogen and explains what each one is for, so you can pick the right skill before doing anything Hydrogen-related. READ THIS FIRST when you're in a fresh Hydrogen workspace and want to know what Claude knows. Trigger words — hd skills, what skills do I have, hd catalog, skill index, skill list, what can claude do in hd, hd-* skills, browser picker, hd setup, hd container info, hd networking, hd volume, hd ports.+---++# Hydrogen Skill Catalog++You're running inside a Hydrogen workspace: the **WSL2 Ubuntu distro+`Adom-Workspace`**. Hydrogen ships a curated catalog of public skills (all+named `hd-*`) so your Claude knows about Hydrogen's own interface, networking, setup+flow, and gotchas. They are BUNDLED into the Hydrogen bootstraps (adom/hydrogen-bootstrap ships the shared/ set, adom/hydrogen-windows-bootstrap the wsl2/ set) and deployed **flat into+`~/.claude/skills/<name>/SKILL.md`** automatically.++## How the catalog is bucketed (and what you actually have)++The public skills live in two buckets in the Hydrogen repo under+`skills/public-facing/`:++- **`shared/`** — topics that do not depend on the workspace's internals.+- **`wsl2/`** — the topics that are specific to the `Adom-Workspace` distro.++The bootstraps deploy both buckets: `shared/` rides adom/hydrogen-bootstrap and the+`wsl2/` set rides adom/hydrogen-windows-bootstrap. You get the whole catalog.++## Shared skills (always present)++| Skill | What it covers |+|-------|----------------|+| `hydrogen-skill-catalog` | This file — read first to know what's available. |+| `hydrogen-golden-image` | Your workspace is a pre-baked golden WSL2 image — the adom/core wiki package (gallia's replacement), CLIs, claude, code-server, settings, and these skills are baked in (not installed by setup); how to update. |+| `hydrogen-skill-loop` | (Maintainers) The loop to fix a wrong/stale Hydrogen skill: verify vs the live Hydrogen, fix it live, write it back to the repo, bake it into the next image. |+| `hydrogen-who-am-i` | Answer "who am I / what can I do here" — the auto-question Hydrogen injects on first launch. |+| `hydrogen-adom-auth` | Adom login/logout, auth intent flow, session token, profile menu. |+| `hydrogen-claude-auth` | How Claude Code signs in: OAuth via Browser Picker, credential backup, the `claude-auth` step. |+| `hydrogen-api` | Control API reference (`127.0.0.1:47084`). |+| `hydrogen-desktop-sse` | Hydrogen's local workspace API + SSE — adom-cli inside the workspace talks to Hydrogen, not cloud Hydrogen. |+| `hydrogen-monitor` | Watch the workspace in real-time via SSE; composes with Claude's Monitor tool. |+| `hydrogen-ui` | Hydrogen's menus, dialogs, panels, programmatic UI control via CDP, CSS selectors. |+| `hydrogen-open-url` | The decision guide for "open a website": the six ways to open a URL (webview tab, Hydrogen window, Pup, native browser, picker, headless curl) and when to pick each. |+| `hydrogen-browser-picker` | Every URL Hydrogen opens routes through a 5-layer interception into a picker dialog (AI-friendly 5s countdown). |+| `hydrogen-wiki-review` | After editing any wiki.adom.inc page, load it in pup so the user can review the rendered result (don't just report the commit). |+| `hydrogen-claude-management` | First-class API for the Claude conversation tabs: list/open/close/switch, read per-conversation state + on-disk session GUID, type into a SPECIFIC conversation (instant/animated) + submit, and turn on Remote Control for a claude.ai/mobile cloud URL. Address by stable context id. |+| `hydrogen-permissions` | Why mic/camera/clipboard/notifications "just work" — Hydrogen auto-grants WebView2 permissions, so webview apps see no Allow prompts. |+| `hydrogen-adom-bridge` | What Hydrogen and Adom Bridge (ab) are + how they work together — ab is your reach onto the user's real OS (create files/folders, run shell, OS screenshots, launch apps, browsers, KiCad/Fusion). |+| `hydrogen-bridges` | Built-in KiCad/Fusion/Puppeteer bridges + extensible wiki catalog (e.g. Blender) + full ab capability list (usb, caption, record…). |+| `hydrogen-eval` | Inject JS into ANY Hydrogen surface (shell/workbench/wiki/Claude) via POST /eval-in; build add-ons, overlays, highlights. |+| `hydrogen-adom-menu` | The upper-left Adom logo menu: Settings, Ports, API Explorer, Doctor, Run Wake Check, DevTools, Setup Steps, Virgin Reset, About dialog, version readout. |+| `hydrogen-doctor` | The Doctor (Adom menu + GET/POST /doctor): 17 end-to-end health checks with plain-English hover explanations, a safe one-click fix, and a confirm-gated workspace restart. |+| `hydrogen-settings` | Hydrogen's Settings dialog + the full preferences tree (theme, vim mode, 3D control style, launch-on-boot, ab window behavior). |+| `hydrogen-dock` | The app launcher rail: the adom-curated global list + user-added wiki apps, the dock block apps declare so Hydrogen can launch them, and the free orbital loading screen. |+| `hydrogen-file-transfer` | Move files BOTH ways between the WSL2 workspace and the Windows PC (/mnt/c, \\wsl$, adom-bridge-cli relay). |+| `hydrogen-tab-icons` | Webview tab icon customization (displayIcon API, brand colors, MDI/SVG). |+| `hydrogen-profile-menu` | The avatar dropdown: profile/repos/molecules links and logout. |+| `hydrogen-embedded-ad` | Hydrogen ↔ Adom Bridge embedded mode: tray, hidden ab, footer pill. |+| `hydrogen-self-screenshot` | How Claude screenshots Hydrogen panels + any host window (window control, multi-monitor), ralph loops, resize-before-Read rule. |+| `hydrogen-capture-share` | The screen-share + "AI wants access" approval + countdown the AI triggers to capture the editor; tab/screen scopes, Webview/Pup window mode. |+| `hydrogen-recording` | Record screen/window — Hydrogen's NATIVE WGC/DXGI recorder (h264/h265 mp4 → `recordings/`, no picker/banner, "record kicad"/"record whole screen", max-duration cap), plus ab desktop recording + the tab-vs-desktop footgun. |+| `hydrogen-screen-lock` | Hydrogen screen capture and the display wake-lock: Hydrogen's native screenshots (CDP) + recording (WGC/DXGI) hold NO wake-lock, so Hydrogen has no burn-in leak; the cap + "● Recording" indicator; `powercfg /requests` to diagnose. |+| `hydrogen-notifications` | Reach the user — OS Windows toasts + emergency taskbar flash via `notify_user`, AND the in-app `POST /ui/toast` (toast inside the Hydrogen window). |+| `hydrogen-captions` | Paint labeled text on the user's screen — a Win32 always-on-top caption overlay for demos / step callouts. |+| `hydrogen-welcome` | The static welcome page shown after setup completes. |+| `hydrogen-overview` | Master skill index, grouped by category. |++## Workspace skills (the `wsl2/` bucket)++| Skill | What it covers |+|-------|----------------|+| `hydrogen-container` | This workspace's spec — Ubuntu 24.04, code-server 4.112.0, what's pre-installed, env vars. |+| `hydrogen-topology` | The three layers and how commands route to reach the workspace. |+| `hydrogen-networking` | Port architecture, hostnames, code-server proxy, host access, NEVER-do-these rules. |+| `hydrogen-ports` | Forwarding workspace services to Windows. |+| `hydrogen-port-watcher` | The dynamic port-forward daemon for extension OAuth callbacks. |+| `hydrogen-volume` | Where your code lives, what persists, what a reset wipes, how to copy files out. |+| `hydrogen-container-stats` | The title-bar CPU/RAM indicator and how its stats are gathered. |+| `hydrogen-setup` | The setup panel UI — Run All, Rollback, Virgin Reset toggles. |+| `hydrogen-setup-steps` | What each setup step did to tool your workspace. |+| `hydrogen-workspace-lifecycle` | Starting, stopping, restarting and repairing the `Adom-Workspace` distro. |+| `hydrogen-workspace-monitoring` | Frontend monitoring of the workspace distro's health. |+| `hydrogen-wake-repair` | Recovering the workspace after the laptop sleeps or wakes. |++## What's NOT in your workspace — internal dev skills++The Hydrogen repo also has skills under `skills/dev-internal-facing/` (hydrogen-debug, hydrogen-dev,+hydrogen-pitfalls, hydrogen-settings, an internal hydrogen-setup-steps deep-dive,+hydrogen-vm-test, and more). These are **Adom-employee-only development skills** — Hydrogen+build pipeline, debugging the Tauri/WebView2 source, internal architecture,+postmortems. They live in the Hydrogen repo but are **NEVER** deployed to user+workspaces.++The split is enforced by the bootstrap bundling, which only ships+`skills/public-facing/{shared,wsl2}/hd-*/` — never `dev-internal-facing/`.++| Folder | Audience | Deployed to user workspaces? |+|--------|----------|------------------------------|+| `public-facing/shared/` | End users of Hydrogen | **Yes** |+| `public-facing/wsl2/` | End users of Hydrogen | **Yes** |+| `dev-internal-facing/` | Adom employees who develop Hydrogen | **No** (repo-only) |++## How to use this catalog++1. In a fresh Hydrogen workspace, scan this table for the most relevant `hd-*` skill+   before answering an Hydrogen-related question.+2. Skill descriptions are loaded automatically by skill-pilot at session start.+3. If a topic seems missing, it may be a dev-internal-facing skill (repo-only) —+   ask the user to check the Hydrogen repo.++## When skills get refreshed++Skills are deployed by the bootstrap postinstall at install/bake time. To refresh after a skills change, the workspace picks up new bootstrap versions via `adom-wiki pkg update` (the `adom/hook` prompt hook) — or a fresh golden image. There is no `install-hd-skills` setup step (removed).
skills/hydrogen-wake-repair/SKILL.mdadded+144
@@ -0,0 +1,144 @@+---+name: hydrogen-wake-repair+description: >+  How Hydrogen automatically repairs the workspace connection after the+  laptop wakes from sleep: the wake-heal cascade, the header wake indicator with+  its live info tooltip, the Settings > Desktop > Wake section (heal toggle,+  indicator toggle, linger slider), and the /wake/* control API endpoints. Read+  this when the user reports Hydrogen did not reconnect after sleep, sees a "cannot+  reconnect" dialog, asks what the sunrise/sync icon in the header is, or wants+  to test or configure wake behavior.+  Trigger words: wake from sleep, laptop sleep, lid close, sleep resume, resume+  from sleep, reconnect after sleep, wake repair, wake heal, wake indicator,+  sunrise icon, cannot reconnect, workspace stuck after wake, wake status,+  wake simulate, wake settings, run wake check, wake check menu, backend+  banner, workspace stopped responding, reconnect button.+---++# Hydrogen Wake Repair (reconnect after laptop sleep)++> The heal cascade below manipulates the `Adom-Workspace` WSL distro.++When the laptop sleeps, WSL2 networking and code-server often come back wedged:+the user reopens the lid and sees a dead editor pane or VS Code's "Cannot+reconnect" dialog. Hydrogen detects the wake natively (Win32 power notifications,+both manual and automatic resume, deduplicated) and runs an automatic repair so+the user should normally have to do NOTHING.++## What the user sees++- **Wake indicator** in the header, to the right of the lightbulb (only if+  enabled in settings, default off): a spinning sync icon while healing, a+  sunrise icon when the heal finished, an alert icon if it failed.+- Hovering the small **info (i) icon** next to it shows a live tooltip with the+  current phase and the last log lines, updating as the heal runs.+- The indicator lingers for a configurable time after the wake (default 60s),+  then hides itself.++## Running it manually: Adom menu > "Run Wake Check"++The whole cascade can be triggered on demand from the Adom menu ("Run Wake+Check", right after API Explorer). The tooltip behavior is deliberate:++- **Manual trigger** (menu item): the wake icon appears AND the info tooltip+  pins itself open so the user can watch every phase live, then unpins shortly+  after the heal reaches a terminal phase (with a 45s safety timeout).+- **Automatic wake** (real sleep resume, or `POST /wake/simulate`): icon only,+  no tooltip. Hovering the (i) icon shows it. An unrequested tooltip popping+  over the editor would be noise.++## The backend watchdog banner (catches what wake events miss)++Wake detection covers sleep resume, but a workspace can die without any wake+event (WSL wedge, code-server crash). The VS Code panel therefore polls+`/workspace/health` every 8 seconds for its whole life. Two consecutive misses+of `editor_will_load` show an amber banner over the editor: "Your workspace+stopped responding - this can happen after your laptop sleeps", with a+**Reconnect** button that runs the same heal cascade (`POST /wake/simulate`).+`editor_will_load` is honest: it is a real HTTP GET of code-server's+`/healthz` (success or redirect), not a bare TCP connect, because a wedged+code-server can still accept TCP while serving nothing.++For a full-stack diagnosis beyond wake issues, use the Doctor+(Adom menu > "Doctor...", or `GET/POST /doctor`, see `hydrogen-doctor`); its+"Fix problems" button runs this same cascade plus before/after evidence.++## Settings (Settings window > Desktop > Wake)++| Setting | Key | Default | Meaning |+|---|---|---|---|+| Repair connection after wake | `desktop.wake_heal` | on | Run the heal cascade on resume. Turning it off means wakes are only logged. |+| Show wake indicator | `desktop.wake_indicator` | off | Show the header indicator + info tooltip after a wake. |+| Indicator linger | `desktop.wake_indicator_linger` | 60s | Slider (0-600s, 15s steps): how long the indicator stays visible after a wake. |++If the user complains about reconnects, suggest turning the indicator ON so+they (and you) can watch what the heal is doing.++## Control API endpoints++On the Hydrogen control API (port from `~/.adom/hydrogen-control-url`, see `hydrogen-api`):++- `GET /wake/status` — full state: `last_sleep_at`, `last_wake_at`, `wake_kind`,+  current `phase`, `healing`, `heal_enabled`, and the recent log (capped 40+  lines). **Always read this first** when debugging a wake complaint.+- `POST /wake/simulate` — fires a fake wake event and runs the real heal+  cascade end-to-end. Safe to use for testing; takes ~20-60s on a healthy+  system.+- `POST /wake/config` `{"heal_enabled": true|false}` — toggle healing at+  runtime (the settings toggle calls this).++## What the heal actually does (so you can explain or debug it)++Three phases, visible in the `/wake/status` log:++1. **Backend** — polls workspace health up to 8 rounds x 12s. Restarts+   code-server at round 2 if still down. If a WSL wedge is suspected, runs+   `wsl --terminate Adom-Workspace` at round 4 and lets the distro boot fresh.+   A full `wsl --shutdown` is NEVER automatic (it would kill other distros);+   that remains a manual last resort.+2. **Token re-stamp** — `/var/run/adom/api-key` lives on tmpfs inside the+   distro, so a distro restart wipes it. Hydrogen re-writes it from the saved+   session so agents inside the workspace keep working.+3. **Pane** — checks the VS Code pane up to 3 x 15s for a stuck "Cannot+   reconnect" dialog and, only if stuck, reloads the editor iframe (pane-only+   reload, not the whole app).++## From inside the workspace (your perspective)++A laptop sleep looks to you like a frozen clock and a brief network blackout.+After a wake: your API key file may have just been re-stamped, and code-server+may have restarted underneath you. If the user says "it didn't come back":++1. `GET /wake/status` and read the log — did the heal run, and where did it+   stop?+2. If `heal_enabled` is false, ask the user if they want it on+   (`POST /wake/config`).+3. `POST /wake/simulate` reproduces the whole flow on demand.+4. If the heal reports failure repeatedly, the workspace may need a manual+   restart: Adom menu > Restart Container (which shows a live log of what it+   is doing).++## The reveal invariant (2026-08-06, the overnight grey-pane disaster)++The pane phase above got a hard rule after an overnight sleep left a dead grey+editor pane revealed all morning:++- **The editor pane may only be revealed after the iframe has (re)loaded+  against a backend CONFIRMED serving** (`/workspace/health` reports+  `editor_will_load`) **and painted.** A paint timeout alone proves nothing: a+  stale error page passes both a timeout and a healthy-backend check.+- **":8821 up" means the backend is alive, NOT that the iframe reloaded onto+  it.** If the iframe last loaded while the backend was dead, it is a stale+  corpse: force one reload onto the live backend before any reveal+  (the `reloadedAgainstHealthy` gate in PanelVisualStudioCode.svelte).+- While the backend is unreachable: keep the orbital splash up and hard-reload+  the iframe (about:blank then the URL) on a bounded cadence. Never reveal.+- The post-wake stuck-dialog reload waits up to ~60s for+  `editor_will_load` before reloading the pane (wake_heal.rs) so it cannot+  reload INTO a dead backend.++Testing rule (how round 1 shipped broken): **screenshot the RECOVERY frame,+not just the outage.** Kill code-server inside the distro, verify the splash+(outage frame), bring it back, and verify the editor self-reveals with real+content (recovery frame). Round 1 passed the outage and revealed a stale error+page on recovery; only the recovery screenshot caught it.