bootstrap
Adom Hydrogen (Windows / WSL2)
Public Made by Adomby adom
The Windows (WSL2) platform layer for Hydrogen.
← Commit history
Publish 0.3.3
13 files changed
+177−177
package.json+2−2page.json+2−2skills/hydrogen-container-stats/SKILL.md+11−11skills/hydrogen-container/SKILL.md+11−11skills/hydrogen-networking/SKILL.md+19−19skills/hydrogen-port-watcher/SKILL.md+31−31skills/hydrogen-ports/SKILL.md+26−26skills/hydrogen-setup-steps/SKILL.md+15−15skills/hydrogen-setup/SKILL.md+12−12skills/hydrogen-topology/SKILL.md+12−12skills/hydrogen-volume/SKILL.md+10−10skills/hydrogen-workspace-lifecycle/SKILL.md+17−17skills/hydrogen-workspace-monitoring/SKILL.md+9−9package.json+2−2@@ -4,7 +4,7 @@ "type": "bootstrap", "title": "Adom Hydrogen (Windows / WSL2)", "brief": "The Windows (WSL2) platform layer for Hydrogen.",- "version": "0.3.2",+ "version": "0.3.3", "description": "The Windows platform layer for Hydrogen, where the workspace runs in a WSL2 Ubuntu distro. Depends on adom/hydrogen-bootstrap (the platform-generic layer, which bundles the generic hydrogen-* skills) and adds everything specific to the WSL2 runtime: the WSL2/networking/lifecycle hydrogen-* skills (BUNDLED here by design, John+Kyle 2026-07-16) and the WSL2 code-server workbench seed. Sibling adom/hydrogen-mac-bootstrap carries the parallel mac skills. This is the package the golden WSL2 image installs.", "org": "adom", "platform": "linux",@@ -19,7 +19,7 @@ "install": "./install.sh" }, "dependencies": {- "adom/hydrogen-bootstrap": "^0.3.2",+ "adom/hydrogen-bootstrap": "^0.3.3", "adom/adom-shotlog": "^0.24.0" }, "files": [
page.json+2−2@@ -4,7 +4,7 @@ "slug": "hydrogen-windows-bootstrap", "title": "Adom Hydrogen (Windows / WSL2)", "brief": "The Windows (WSL2) platform layer for Hydrogen.",- "version": "0.3.2",+ "version": "0.3.3", "author": { "name": "John Lauer", "email": "[email protected]"@@ -27,7 +27,7 @@ "install": "./install.sh" }, "dependencies": {- "adom/hydrogen-bootstrap": "^0.3.2",+ "adom/hydrogen-bootstrap": "^0.3.3", "adom/adom-shotlog": "^0.24.0" }, "files": [
skills/hydrogen-container-stats/SKILL.md+11−11@@ -1,18 +1,18 @@ --- name: hydrogen-container-stats-description: HD's workspace stats indicator in the top-right of the title bar — two thin progress bars (CPU + RAM) labelled "Container" plus an info tooltip on hover that shows the workspace name, CPU vs total cores, RAM usage vs limit, disk usage, image/distro, ID, and creation date. Polls once per second when running, every 5 seconds when stopped. Status badges show stopped / starting / restarting / restart-needed states. Use this skill when the user asks about CPU/RAM usage, the resource bars in HD's title bar, workspace disk usage, the "restart needed" badge, why bars are red/yellow, or what's in the tooltip. Trigger words — container stats, workspace stats, container cpu, container ram, container disk, resource bars, cpu bar, ram bar, container tooltip, container indicator, top bar stats, restart needed badge, container stopped badge, container starting, workspace_stats, distro stats, wsl stats.+description: Hydrogen's workspace stats indicator in the top-right of the title bar — two thin progress bars (CPU + RAM) labelled "Container" plus an info tooltip on hover that shows the workspace name, CPU vs total cores, RAM usage vs limit, disk usage, image/distro, ID, and creation date. Polls once per second when running, every 5 seconds when stopped. Status badges show stopped / starting / restarting / restart-needed states. Use this skill when the user asks about CPU/RAM usage, the resource bars in Hydrogen's title bar, workspace disk usage, the "restart needed" badge, why bars are red/yellow, or what's in the tooltip. Trigger words — container stats, workspace stats, container cpu, container ram, container disk, resource bars, cpu bar, ram bar, container tooltip, container indicator, top bar stats, restart needed badge, container stopped badge, container starting, workspace_stats, distro stats, wsl stats. --- -# HD Workspace Stats Indicator+# Hydrogen Workspace Stats Indicator > This is the WSL2-runtime version (default). The legacy Docker equivalent > (`HD_RUNTIME=docker`) is in the docker/ bucket. -The top-right of HD's title bar (next to the audio/video icons and your profile avatar) shows a tiny `Container` block with two horizontal progress bars — CPU% and RAM% — that animate in real-time. Hovering brings up a tooltip with the full workspace details. Under the WSL2 runtime these numbers now reflect the **`Adom-Workspace` distro**, not a Docker container — but the UI is unchanged, so the header still reads "Container".+The top-right of Hydrogen's title bar (next to the audio/video icons and your profile avatar) shows a tiny `Container` block with two horizontal progress bars — CPU% and RAM% — that animate in real-time. Hovering brings up a tooltip with the full workspace details. Under the WSL2 runtime these numbers now reflect the **`Adom-Workspace` distro**, not a Docker container — but the UI is unchanged, so the header still reads "Container". ## How often it polls -There's an active polling loop in HD's title bar that asks the runtime for fresh stats on a timer:+There's an active polling loop in Hydrogen's title bar that asks the runtime for fresh stats on a timer: - **Every 1 second** when the workspace is `running` — for live, smooth bar animation - **Every 5 seconds** when it's `stopped`, `starting`, `restarting`, or `restart needed` — saves cycles when nothing's changing@@ -58,8 +58,8 @@ The `Container` text in the section header gets an inline status badge depending |-------|---------|-------| | (no badge) | Running normally | normal | | `stopped` | Distro registered but not running | red |-| `starting` | HD is starting the distro / code-server | yellow |-| `restarting` | HD is restarting the distro | yellow |+| `starting` | Hydrogen is starting the distro / code-server | yellow |+| `restarting` | Hydrogen is restarting the distro | yellow | | `restart needed` | The distro or code-server is unreachable (usually a WSL2 hiccup after Windows wake) | red | When `restart needed` shows, open the Adom menu → Restart Workspace (see the `hydrogen-ui` skill for the Adom menu). A "Restart" here is `wsl --terminate Adom-Workspace` + re-ensure code-server — NOT `docker restart`.@@ -73,13 +73,13 @@ When `restart needed` shows, open the Adom menu → Restart Workspace (see the ` ### The benign `[docker] unhealthy` log line -You will sometimes see this in HD's log even on the WSL2 path:+You will sometimes see this in Hydrogen's log even on the WSL2 path: ``` [docker] Container runtime unhealthy — exec failed, needs restart ``` -**Under WSL this is BENIGN NOISE.** It's a leftover hd-docker heartbeat with no container bound to it — there is no Docker container in WSL mode, so "exec failed" is expected and meaningless. It does NOT mean your workspace is broken.+**Under WSL this is BENIGN NOISE.** It's a leftover hydrogen-docker heartbeat with no container bound to it — there is no Docker container in WSL mode, so "exec failed" is expected and meaningless. It does NOT mean your workspace is broken. The real WSL health signal to watch for is: @@ -95,10 +95,10 @@ If you want the same stats data your AI can hit directly via the control API: ```bash # From inside the distro — query the control API on the host-curl -s "$(cat ~/.adom/hd-control-url)/container-stats"+curl -s "$(cat ~/.adom/hydrogen-control-url)/container-stats" ``` -(Reach the control API at `127.0.0.1` — WSL2 mirrored networking shares loopback with the Windows host. The port is **dynamic per launch**; read the live URL from `~/.adom/hd-control-url` rather than hardcoding it.)+(Reach the control API at `127.0.0.1` — WSL2 mirrored networking shares loopback with the Windows host. The port is **dynamic per launch**; read the live URL from `~/.adom/hydrogen-control-url` rather than hardcoding it.) Returns JSON like: ```json@@ -141,7 +141,7 @@ Or if the workspace is in a broken state: **"Why does RAM stay constant at ~4% even when I'm doing nothing?"** Code-server, the relay, gallia, the adom-vscode HTTP API, etc. all run in the distro all the time. ~700 MB baseline is normal. -**"The 'restart needed' badge appeared — what happened?"** Almost always a WSL2 hiccup after Windows wake/sleep, leaving the distro or code-server unreachable. Click Restart Workspace in the Adom menu (top-left). HD will `wsl --terminate Adom-Workspace`, re-ensure code-server, and the badge clears.+**"The 'restart needed' badge appeared — what happened?"** Almost always a WSL2 hiccup after Windows wake/sleep, leaving the distro or code-server unreachable. Click Restart Workspace in the Adom menu (top-left). Hydrogen will `wsl --terminate Adom-Workspace`, re-ensure code-server, and the badge clears. **"The log says `[docker] … unhealthy` — is my workspace broken?"** No. Under WSL that line is a benign leftover heartbeat with no container bound. Look at `[wsl] Workspace unhealthy …` for the real signal. See "The benign `[docker] unhealthy` log line" above.
skills/hydrogen-container/SKILL.md+11−11@@ -7,7 +7,7 @@ description: Context for Claude Code running inside a Hydrogen WSL2 workspace di WSL2-runtime version (default). Legacy Docker container runtime (`HD_RUNTIME=docker`) is in the docker/ bucket. -You are running inside the **`Adom-Workspace` WSL2 distro** managed by Hydrogen (HD). HD is the flagship Adom desktop app — it manages your WSL2 workspace, bridges to desktop apps, and provides VS Code + Claude Code.+You are running inside the **`Adom-Workspace` WSL2 distro** managed by Hydrogen (ah). Hydrogen is the flagship Adom desktop app — it manages your WSL2 workspace, bridges to desktop apps, and provides VS Code + Claude Code. ## The workspace — exact facts (don't guess) @@ -26,17 +26,17 @@ You are running inside the **`Adom-Workspace` WSL2 distro** managed by Hydrogen | Workspace | `/home/adom/project` (lives directly in the distro's ext4 filesystem) | | Pre-installed | Node 18 + npm, Python 3.12, git, gh, curl, wget, jq, build-essential, cmake, pkg-config, libssl-dev | | Code-server runs as | `code-server --bind-addr 0.0.0.0:7380 --auth none --disable-telemetry /home/adom/project` (WSL2 auto-forwards 7380 to Windows `localhost:7380`) |-| Runtime source | `hydrogen-desktop/src-tauri/crates/hd-app/src/runtime/wsl.rs` (selector `runtime/mod.rs::select_runtime()`) |+| Runtime source | `hydrogen-desktop/src-tauri/crates/hydrogen-app/src/runtime/wsl.rs` (selector `runtime/mod.rs::select_runtime()`) | If you ever need to confirm: `cat /etc/os-release`, `uname -m`, `/usr/lib/code-server/bin/code-server --version`. Don't speculate about alpine/arm64 — Ubuntu 24.04 matches the cloud container. -## Setup is via HD's setup-steps, NOT gallia bootstrap.sh+## Setup is via Hydrogen's setup-steps, NOT gallia bootstrap.sh -HD provisions this distro through its own **setup-steps** flow (Rust code in `hydrogen-desktop/src-tauri/crates/hd-app/src/setup_steps_wsl.rs`, with the runtime mechanics in `hydrogen-desktop/src-tauri/crates/hd-app/src/runtime/wsl.rs`), shown as the "Install Tools" panel in the HD UI. It is a **different code path** than cloud containers, which run `gallia/scripts/bootstrap.sh`.+Hydrogen provisions this distro through its own **setup-steps** flow (Rust code in `hydrogen-desktop/src-tauri/crates/hydrogen-app/src/setup_steps_wsl.rs`, with the runtime mechanics in `hydrogen-desktop/src-tauri/crates/hydrogen-app/src/runtime/wsl.rs`), shown as the "Install Tools" panel in the Hydrogen UI. It is a **different code path** than cloud containers, which run `gallia/scripts/bootstrap.sh`. -The WSL cascade is **28 steps** (state file `setup-steps-wsl.json`) vs the legacy Docker flow's 24. Most tooling is NOT installed by a step — it's BAKED into `adom-golden.tar.gz` at image-build time (gallia, the 8 Adom CLIs, the Claude Code extension, code-server, VS Code settings, and all `hd-*` skills). The one exception is the `claude` CLI, which is installed at RUNTIME by step 13 `install-claude-cli` (its self-setup needs a live session). The Docker `pull-image` / `create-container` / `start-container` steps are collapsed into a single step 1, `ensure-workspace`, which runs `wsl --import` of `adom-golden.tar.gz` if the distro isn't already registered. The relay is started by the `start-relay` step. See `hd-golden-image`.+The WSL cascade is **28 steps** (state file `setup-steps-wsl.json`) vs the legacy Docker flow's 24. Most tooling is NOT installed by a step — it's BAKED into `adom-golden.tar.gz` at image-build time (gallia, the 8 Adom CLIs, the Claude Code extension, code-server, VS Code settings, and all `hd-*` skills). The one exception is the `claude` CLI, which is installed at RUNTIME by step 13 `install-claude-cli` (its self-setup needs a live session). The Docker `pull-image` / `create-container` / `start-container` steps are collapsed into a single step 1, `ensure-workspace`, which runs `wsl --import` of `adom-golden.tar.gz` if the distro isn't already registered. The relay is started by the `start-relay` step. See `hydrogen-golden-image`. -When debugging install issues here, the source of truth is `setup_steps_wsl.rs` (and `runtime/wsl.rs`) — its step IDs (`ensure-workspace`, `install-adom-vscode`, `set-env-vars`, `inject-api-key`, `start-relay`, `claude-auth`, etc.) map 1:1 to what ran on this distro. There is NO `install-claude-ext` / `install-claude-cli` / `install-gallia` / `write-vscode-settings` step anymore — those are baked. Do NOT chase bugs into `bootstrap.sh` first — that script lives in the baked image but HD itself never invokes it. (For the legacy Docker `setup_steps.rs` flow see the docker/ bucket.)+When debugging install issues here, the source of truth is `setup_steps_wsl.rs` (and `runtime/wsl.rs`) — its step IDs (`ensure-workspace`, `install-adom-vscode`, `set-env-vars`, `inject-api-key`, `start-relay`, `claude-auth`, etc.) map 1:1 to what ran on this distro. There is NO `install-claude-ext` / `install-claude-cli` / `install-gallia` / `write-vscode-settings` step anymore — those are baked. Do NOT chase bugs into `bootstrap.sh` first — that script lives in the baked image but Hydrogen itself never invokes it. (For the legacy Docker `setup_steps.rs` flow see the docker/ bucket.) ## VS Code extension caveats @@ -46,11 +46,11 @@ When debugging install issues here, the source of truth is `setup_steps_wsl.rs` ## adom-cli is authenticated -HD auto-injects the user's session token on every launch. To verify:+Hydrogen auto-injects the user's session token on every launch. To verify: ```bash adom-cli carbon user get ```-If this returns user data, all adom-cli commands work (containers, repos, orgs, wiki, etc.). If it fails, the user needs to log in via HD's login page.+If this returns user data, all adom-cli commands work (containers, repos, orgs, wiki, etc.). If it fails, the user needs to log in via Hydrogen's login page. ## Relay server is running @@ -59,7 +59,7 @@ The adom-bridge-cli relay runs on ports 8765 (WebSocket) / 8766 (HTTP) inside th Check health: `curl -sf http://127.0.0.1:8766/health` Check desktop connection: `adom-bridge-cli ping` -The Windows host control API is reachable from inside the distro at `127.0.0.1` — WSL2 mirrored networking shares loopback with the Windows host. The port is dynamic per launch, so read the live URL from `~/.adom/hd-control-url` (`http://127.0.0.1:<dynamic>`): `BASE="$(cat ~/.adom/hd-control-url)"; curl "$BASE/health"`.+The Windows host control API is reachable from inside the distro at `127.0.0.1` — WSL2 mirrored networking shares loopback with the Windows host. The port is dynamic per launch, so read the live URL from `~/.adom/hydrogen-control-url` (`http://127.0.0.1:<dynamic>`): `BASE="$(cat ~/.adom/hydrogen-control-url)"; curl "$BASE/health"`. ## Available bridge commands (when desktop is connected) @@ -110,7 +110,7 @@ adom-bridge-cli desktop_open_folder '{"path": "C:\\Users\\john\\project"}' ## What's different from Adom cloud containers -| Feature | Adom Cloud | HD Local (WSL2) |+| Feature | Adom Cloud | Hydrogen Local (WSL2) | |---------|-----------|-----------------| | Workspace provisioning | Adom platform API | `wsl --import` of `adom-golden.tar.gz` on the user's machine | | Relay connection | wss:// through Cloudflare | ws://localhost:8765 (direct, no TLS) |@@ -121,7 +121,7 @@ adom-bridge-cli desktop_open_folder '{"path": "C:\\Users\\john\\project"}' ## Environment variables -- `ADOM_DESKTOP_MODE=local` — indicates HD local mode+- `ADOM_DESKTOP_MODE=local` — indicates Hydrogen local mode - `HD_RUNTIME=wsl2` — indicates the WSL2 runtime (default); `docker` selects the legacy container runtime - `GALLIA_SERVICE=local` — tells gallia this is a local workspace - `VSCODE_PROXY_URI=http://localhost:7380/proxy/{{port}}/` — code-server's proxy
skills/hydrogen-networking/SKILL.md+19−19@@ -5,8 +5,8 @@ description: > MUST READ before adding ports, exposing a service to your Windows host, referencing host URLs from inside the workspace, or wiring any service communication.- Trigger words — HD port, HD network, port mapping, proxy, 127.0.0.1, loopback,- mirrored networking, hd-control-url,+ Trigger words — Hydrogen port, Hydrogen network, port mapping, proxy, 127.0.0.1, loopback,+ mirrored networking, hydrogen-control-url, VSCODE_PROXY_URI, relay URL, code-server proxy, container networking, ADOM_CARBON_URL, ADOM_HYDROGEN_URL, direct connect, 8770, 7380. ---@@ -18,7 +18,7 @@ description: > ## Core Principle: WSL2 auto-forwards `0.0.0.0` listeners -The HD workspace is a WSL2 distro (`Adom-Workspace`), not a Docker container.+The Hydrogen workspace is a WSL2 distro (`Adom-Workspace`), not a Docker container. WSL2 has a built-in localhost-forwarding feature: **any service that binds `0.0.0.0:<port>` inside the distro is automatically reachable at `127.0.0.1:<sameport>` on Windows** — no Docker `-p` mapping, no proxy hop@@ -48,16 +48,16 @@ All of these are also reachable through code-server's `/proxy/<port>/` URL ## Host-Side Ports (Tauri app, native Windows listeners) -These ports run on the Windows host inside the HD Tauri process. They are+These ports run on the Windows host inside the Hydrogen Tauri process. They are native TCP listeners on Windows — not inside the distro. | Port | Service | Notes | |------|---------|-------| | 1420 | Dev file server | Dev mode only, serves `build/` |-| 8770 | adom-bridge-cli direct connect | Owned by Adom Bridge, NOT HD |-| 47080 | HD discovery server | |-| 47083 | HD reverse proxy | Proxies to code-server |-| 47084 | HD control API | Health, setup, eval, CDP, `/wsl/status`, `/port-forward` |+| 8770 | adom-bridge-cli direct connect | Owned by Adom Bridge, NOT Hydrogen |+| 47080 | Hydrogen discovery server | |+| 47083 | Hydrogen reverse proxy | Proxies to code-server |+| 47084 | Hydrogen control API | Health, setup, eval, CDP, `/wsl/status`, `/port-forward` | | 47085 | WebView2 CDP | Chrome DevTools Protocol | These are configurable via `%APPDATA%\hydrogen-desktop\ports.json`.@@ -66,9 +66,9 @@ These are configurable via `%APPDATA%\hydrogen-desktop\ports.json`. **mirrored networking** shares the loopback interface between the distro and the Windows host, so a Windows listener on `127.0.0.1:<port>` is reachable at the same `127.0.0.1:<port>` from inside the distro — no gateway IP, no firewall rule, no-`0.0.0.0` requirement on the host side. (`host.docker.internal` is a Docker-ism HD+`0.0.0.0` requirement on the host side. (`host.docker.internal` is a Docker-ism Hydrogen does NOT use under WSL2 — inside the distro it resolves to a *different* interface,-not where HD listens, so curls to it fail.)+not where Hydrogen listens, so curls to it fail.) ## Hostnames — reach the host at `127.0.0.1` @@ -83,11 +83,11 @@ you generally don't need it — use `127.0.0.1`. Used for: - `ADOM_CARBON_URL=http://127.0.0.1:{proxy_port}` - `ADOM_HYDROGEN_URL=http://127.0.0.1:{proxy_port}` - Direct connect probe: `http://127.0.0.1:8770/health`-- HD control API: the live URL in `~/.adom/hd-control-url` (`http://127.0.0.1:<dynamic>`)+- Hydrogen control API: the live URL in `~/.adom/hydrogen-control-url` (`http://127.0.0.1:<dynamic>`) -The control port is **dynamic per launch** — read it from `~/.adom/hd-control-url`+The control port is **dynamic per launch** — read it from `~/.adom/hydrogen-control-url` (your non-interactive Bash shells don't source `.bashrc`/`profile.d`, so the env var-alone is unreliable): `BASE="$(cat ~/.adom/hd-control-url)"`.+alone is unreliable): `BASE="$(cat ~/.adom/hydrogen-control-url)"`. ### From the host → distro services (via proxy) ```@@ -122,7 +122,7 @@ code-server proxy. The proxy path is preferred for connection stability: API (port 8770): ```json {- "name": "HD Local WSL",+ "name": "Hydrogen Local WSL", "url": "ws://127.0.0.1:7380/proxy/8765/", "autoConnect": true }@@ -138,7 +138,7 @@ This matches cloud containers where adom-bridge-cli connects via Inside the distro, `VSCODE_PROXY_URI` is set by code-server: ``` https://<slug>.adom.cloud/proxy/{{port}}/ (cloud)-http://localhost:7380/proxy/{{port}}/ (HD local, approximate)+http://localhost:7380/proxy/{{port}}/ (Hydrogen local, approximate) ``` Tools that build proxy URLs should use `VSCODE_PROXY_URI` when@@ -159,9 +159,9 @@ wsl -d Adom-Workspace -- su - adom -c '<cmd>' Windows. WSL2 won't auto-forward it. Bind `0.0.0.0`, or register it with the port-forward registry (see `hydrogen-port-watcher`). 2. **NEVER use `host.docker.internal` for distro→host** communication — it's a- Docker-ism HD doesn't use; inside the distro it resolves to the wrong interface.+ Docker-ism Hydrogen doesn't use; inside the distro it resolves to the wrong interface. Reach the host at `127.0.0.1` (WSL2 mirrored networking shares loopback); read- HD's live control URL from `~/.adom/hd-control-url`.+ Hydrogen's live control URL from `~/.adom/hydrogen-control-url`. 3. **NEVER assume you need a firewall rule or gateway IP to reach the host.** Under WSL2 mirrored networking the host's `127.0.0.1` listeners are shared with the distro's loopback — `127.0.0.1:<port>` just works, no firewall allow needed.@@ -170,6 +170,6 @@ wsl -d Adom-Workspace -- su - adom -c '<cmd>' 5. **NEVER hardcode port numbers** in distro code. Read from env vars (`ADOM_CARBON_URL`, `ADOM_HYDROGEN_URL`) or discover via the direct connect API.-6. **NEVER assume adom-bridge-cli direct connect (8770) is owned by HD.**- It's owned by Adom Bridge. HD's direct-api thread binds to 8770+6. **NEVER assume adom-bridge-cli direct connect (8770) is owned by Hydrogen.**+ It's owned by Adom Bridge. Hydrogen's direct-api thread binds to 8770 as a fallback but Adom Bridge takes priority when both are running.
skills/hydrogen-port-watcher/SKILL.md+31−31@@ -2,7 +2,7 @@ name: hydrogen-port-watcher description: > Port reachability in Hydrogen — and why you do NOT need to set up- port forwarding. Under WSL2 networkingMode=mirrored (HD's default, which the+ port forwarding. Under WSL2 networkingMode=mirrored (Hydrogen's default, which the setup cascade hard-targets), the distro SHARES the Windows loopback, so every port a service binds in the workspace — including `127.0.0.1`-only OAuth callback servers from VS Code extensions (Codex, Copilot, GitLens) — is@@ -14,9 +14,9 @@ description: > I reach my port. --- -# HD Port Watcher — you don't port-watch anymore (mirrored networking does it)+# Hydrogen Port Watcher — you don't port-watch anymore (mirrored networking does it) -> **TL;DR for the AI: do NOT try to set up port forwarding in HD.** Under the+> **TL;DR for the AI: do NOT try to set up port forwarding in Hydrogen.** Under the > default WSL2 `networkingMode=mirrored`, ports just work. If a `localhost:<port>` > from the workspace isn't reachable on Windows, the fix is almost never "forward > the port" — it's "confirm mirrored is on" (see below), or the service didn't@@ -24,10 +24,10 @@ description: > ## Why there's nothing to do (mirrored networking) -HD's setup cascade hard-targets `networkingMode=mirrored` in `.wslconfig`. Under+Hydrogen's setup cascade hard-targets `networkingMode=mirrored` in `.wslconfig`. Under mirrored, the WSL2 distro shares the Windows loopback interface, so **any** listener in the distro — `0.0.0.0:<port>` AND `127.0.0.1:<port>` — is reachable at the same-`localhost:<port>` on Windows with zero setup. This is why HD's own OAuth host-proxy+`localhost:<port>` on Windows with zero setup. This is why Hydrogen's own OAuth host-proxy is explicitly **skipped** under mirrored (`lib.rs`: *"under WSL2 mirrored it's redundant… host proxy not needed"*). @@ -35,7 +35,7 @@ redundant… host proxy not needed"*). The `port-watcher` daemon below existed for the pre-mirroring world: the Docker/NAT runtime, where the distro could NOT reach Windows loopback, so a daemon watched-`/proc/net/tcp` for new listeners and HD spun up host-side TCP proxies. It closed+`/proc/net/tcp` for new listeners and Hydrogen spun up host-side TCP proxies. It closed two gaps that DO NOT EXIST under mirrored: 1. **`127.0.0.1`-only listeners.** NAT-mode WSL2 did NOT forward loopback-only@@ -43,16 +43,16 @@ two gaps that DO NOT EXIST under mirrored: servers that frequently bind `127.0.0.1`; without mirroring the browser redirect to `localhost:{port}/auth/callback?code=...` hit a port that didn't exist on Windows. 2. **Auto-forward lag / wedge.** WSL2 localhost-forwarding can lag or break- even for `0.0.0.0` listeners (a real HD-logged failure mode:+ even for `0.0.0.0` listeners (a real Hydrogen-logged failure mode: "code-server alive in distro but Windows can't reach 127.0.0.1:7380"). The- watcher gives HD a reliable host-side proxy that doesn't depend on WSL2's+ watcher gives Hydrogen a reliable host-side proxy that doesn't depend on WSL2's forwarder. ## The Solution A lightweight daemon inside the distro monitors `/proc/net/tcp` for new listening ports. When one appears (that wasn't there at boot and isn't a known-service), it notifies HD's control API. HD creates a host-side TCP proxy on+service), it notifies Hydrogen's control API. Hydrogen creates a host-side TCP proxy on that same port, forwarding through code-server's `/proxy/{port}` to reach the distro. The browser redirect just works — even for loopback-only callback servers WSL2 wouldn't have forwarded.@@ -62,7 +62,7 @@ servers WSL2 wouldn't have forwarded. ``` WSL2 distro (Adom-Workspace): Windows Host: ┌─────────────────────┐ ┌──────────────────────┐-│ Codex creates server │ │ HD Control API │+│ Codex creates server │ │ Hydrogen Control API │ │ on 127.0.0.1:1455 │ │ (:47084) │ │ (WSL2 won't forward) │ │ │ │ port-watcher.sh │──POST──→ │ /port-forward │@@ -128,10 +128,10 @@ No boot snapshot — the whitelist is the sole source of truth. Services like shotlog can start at any time (days/weeks later) and will never get a host proxy as long as their port is in the whitelist. -The watcher reaches HD at `127.0.0.1:<control>/port-forward` — WSL2 mirrored+The watcher reaches Hydrogen at `127.0.0.1:<control>/port-forward` — WSL2 mirrored networking shares loopback with the Windows host, so `127.0.0.1` from inside the-distro reaches HD's host listener. The control port is dynamic per launch; the-live control URL is in `~/.adom/hd-control-url`.+distro reaches Hydrogen's host listener. The control port is dynamic per launch; the+live control URL is in `~/.adom/hydrogen-control-url`. ## Installation @@ -153,7 +153,7 @@ The script parses `/proc/net/tcp` directly in `awk` — it filters listener rows ## UI: Toast + Port Mappings Dialog -**Toast notification:** When a port is forwarded, HD shows an info toast:+**Toast notification:** When a port is forwarded, Hydrogen shows an info toast: "Port 1455 forwarded to workspace". When removed: "Port 1455 forwarding stopped". Powered by the `port-forward-changed` Tauri event. @@ -179,13 +179,13 @@ Hydrogen. There are TWO distinct forwarding mechanisms. The `/proc/net/tcp` watcher above is **Layer 2**. Layer 1 is a completely separate path — the OAuth-callback-**localhost proxy** baked into HD itself — and it's why VS Code extension logins+**localhost proxy** baked into Hydrogen itself — and it's why VS Code extension logins "just work" without any watcher round-trip. ### Layer 1 — the OAuth-callback localhost proxy (zero-latency, the primary path) -HD intercepts top-level WebView2 navigations via-`setup_frame_navigation_interception()` (`hd-app/src/lib.rs:75`). On every+Hydrogen intercepts top-level WebView2 navigations via+`setup_frame_navigation_interception()` (`hydrogen-app/src/lib.rs:75`). On every navigation it runs `extract_oauth_callback_port()` (`lib.rs:384`), which **triple-URL-decodes** the target URL (`urlencoding::decode` x3) and scans each decode layer — plus the raw and the percent-encoded@@ -194,7 +194,7 @@ decode layer — plus the raw and the percent-encoded `start_oauth_callback_proxy(port)` (`lib.rs:411`), which **pre-binds** `127.0.0.1:<port>` on the Windows host (via `hd_control::reuse_bind_tcp`) and waits up to ~5 min for one inbound request. When the browser redirects to-`localhost:<port>/callback?code=…`, HD's pre-bound listener accepts it and+`localhost:<port>/callback?code=…`, Hydrogen's pre-bound listener accepts it and forwards the full path into the distro via code-server: `http://localhost:<code_server_port>/proxy/<port>/<path>` (`lib.rs:454`), then streams code-server's response back to the browser.@@ -203,19 +203,19 @@ So the callback port is bound the *instant* the OAuth URL is seen leaving the WebView — before the provider ever redirects — which is why Codex / Copilot OAuth completes with zero manual setup and zero watcher latency. -**Control / callback endpoints** (HD control API, port 47084):+**Control / callback endpoints** (Hydrogen control API, port 47084): - `POST /start-oauth-proxy` — manually pre-bind a callback port (same effect as the navigation interceptor; used by the manual fallback).-- `GET /oauth/callback` — HD's own built-in callback receiver (used by the+- `GET /oauth/callback` — Hydrogen's own built-in callback receiver (used by the Claude Code PKCE flow); do not call directly. **Failure mode the AI may see:** if the proxy binds but code-server can't be-reached, HD returns a styled **502 Bad Gateway** page (dark `#0d1117`-background, teal `#00b8b0` "OAuth callback proxy" heading) reading roughly *"HD+reached, Hydrogen returns a styled **502 Bad Gateway** page (dark `#0d1117`+background, teal `#00b8b0` "OAuth callback proxy" heading) reading roughly *"Hydrogen tried to forward this OAuth callback to the container via code-server proxy (port …/proxy/…), but it failed. The extension that started this OAuth flow may need its callback port (…) mapped to the host."* Seeing that page in a browser-means Layer 1 fired but the distro-side proxy hop failed — check the HD log for+means Layer 1 fired but the distro-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 safety net)@@ -225,7 +225,7 @@ URLs through mechanisms that bypass top-level WebView navigations, AND the only thing that surfaces `127.0.0.1`-only callback servers WSL2 silently won't forward. 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 HD exists).+third-party extensions that don't know Hydrogen exists). ### Layer 3 — manual @@ -236,21 +236,21 @@ third-party extensions that don't know HD exists). If the host port is already taken by another Windows app, the forwarding fails silently. The OAuth callback will break. Mitigation: extensions-typically pick a different random port on retry. HD logs the conflict.+typically pick a different random port on retry. Hydrogen logs the conflict. ## How OAuth Callbacks Work End-to-End 1. Extension (Codex) starts HTTP server on `127.0.0.1:1455` inside the distro 2. port-watcher.sh detects port 1455 (not in boot snapshot, not known) — note WSL2 would NOT have auto-forwarded this loopback-only listener-3. Watcher POSTs `{"port":1455,"action":"open"}` to HD-4. HD creates TCP proxy: `localhost:1455` → code-server `/proxy/1455/`+3. Watcher POSTs `{"port":1455,"action":"open"}` to Hydrogen+4. Hydrogen creates TCP proxy: `localhost:1455` → code-server `/proxy/1455/` 5. Extension opens browser with `redirect_uri=http://localhost:1455/callback` 6. User authenticates, browser redirects to `localhost:1455/callback?code=...`-7. HD's proxy receives the request, forwards into the distro via code-server+7. Hydrogen's proxy receives the request, forwards into the distro via code-server 8. Extension receives callback, completes auth 9. Extension closes its server, port 1455 disappears-10. Watcher POSTs `{"port":1455,"action":"close"}`, HD removes proxy+10. Watcher POSTs `{"port":1455,"action":"close"}`, Hydrogen removes proxy ## Debugging @@ -264,7 +264,7 @@ wsl -d Adom-Workspace -u adom -- bash -c "cat /proc/net/tcp | awk '\$4 == \"0A\" # Check the watcher's own log wsl -d Adom-Workspace -u adom -- cat /tmp/port-watcher.log -# Check what HD has forwarded (from Windows host)+# Check what Hydrogen has forwarded (from Windows host) curl -sf http://127.0.0.1:47084/port-forward # Manually forward a port (for testing, from Windows host)@@ -272,7 +272,7 @@ curl -sf -X POST http://127.0.0.1:47084/port-forward \ -H Content-Type:application/json \ -d '{"port":1455,"action":"open"}' -# Check HD log for port-fwd events+# Check Hydrogen log for port-fwd events # Look for [port-fwd] entries ```
skills/hydrogen-ports/SKILL.md+26−26@@ -1,21 +1,21 @@ --- name: hydrogen-ports-description: How HD does port forwarding between your WSL2 workspace and your Windows machine — WSL2's automatic `0.0.0.0` localhost-forwarding (no Docker `-p` map), 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.+description: How Hydrogen does port forwarding between your WSL2 workspace and your Windows machine — WSL2's automatic `0.0.0.0` localhost-forwarding (no Docker `-p` map), 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. --- -# HD Ports — forwarding workspace services to your Windows host+# Hydrogen Ports — forwarding workspace services to your Windows host > This is the WSL2-runtime version (default). For the legacy Docker container > runtime (`HD_RUNTIME=docker`) see the docker/ bucket. -The HD workspace is a WSL2 distro (`Adom-Workspace`), not a Docker container.+The Hydrogen workspace is a WSL2 distro (`Adom-Workspace`), not a Docker container. There is **no Docker `-p` port mapping** — 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), HD's port-forward+(`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`@@ -51,13 +51,13 @@ Examples: **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 HD's own-services (HD's live control URL is in `~/.adom/hd-control-url`), and the proxy+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 — HD's+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: @@ -65,7 +65,7 @@ port-forward registry, serviced by the port-watcher daemon (see 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 HD+- 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.@@ -73,22 +73,22 @@ port-forward registry, serviced by the port-watcher daemon (see 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 HD proxies it.+ **register the port** so Hydrogen proxies it. ### Register a port (from inside your workspace) ```bash-# Tell HD: "please bind localhost:5555 on Windows and forward into the distro"+# 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 HD-managed proxy AND+- `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 HD decide based on heuristics (defaults to external).+- `either` — let Hydrogen decide based on heuristics (defaults to external). ### Unregister ```bash@@ -102,22 +102,22 @@ adom-cli port-forward list ## The Port Mappings dialog -Open via: HD Adom menu → "Port Mappings", or `POST http://127.0.0.1:47084/setup/panel/show`+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`- (HD-managed host proxies, for loopback-only / unreliable cases)+ (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. -## HD's host-side port registry+## Hydrogen's host-side port registry -HD reads/writes its host-side port assignments at+Hydrogen reads/writes its host-side port assignments at `%APPDATA%\hydrogen-desktop\ports.json`. The `PortConfig` struct-(`hd-control/src/ports.rs`) holds exactly four service ports —+(`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@@ -132,7 +132,7 @@ Defaults (you can override via ports.json): | code-server | 7380 | | Discovery server | 47080 | | Reverse proxy (`proxy`) | 47083 |-| HD control API (`control`) | 47084 |+| 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) |@@ -140,7 +140,7 @@ Defaults (you can override via ports.json): **Conflict resolution is NOT "next sequential port."** On startup `PortConfig::resolve_available()` checks `proxy`, `control`, and `cdp`; if a-preferred fixed port is taken, HD binds an **ephemeral `127.0.0.1:0`** port (the+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@@ -152,7 +152,7 @@ distro's mirrored port). So a busy box does NOT predictably land on 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` (`hd-app/src/lib.rs` `get_ports`). `ports.json` is the single source+`PortConfig` (`hydrogen-app/src/lib.rs` `get_ports`). `ports.json` is the single source of truth every consumer reads. ## Inside vs outside — which URL to use@@ -164,7 +164,7 @@ of truth every consumer reads. | 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 | HD's own control API (on Windows host) | `$(cat ~/.adom/hd-control-url)` → `http://127.0.0.1:<dynamic>` (port is dynamic per launch) |+| 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 @@ -179,15 +179,15 @@ of truth every consumer reads. - 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"`.-- HD auto-detects callback URLs and starts a proxy for them automatically in- many cases (see HD log for `[oauth] Callback port X detected`), but+- 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 HD-logged failure mode). The port-forward registry / port-watcher+ 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 HD to re-establish the forward.+ Or restart Hydrogen to re-establish the forward. ## Related skills @@ -197,7 +197,7 @@ of truth every consumer reads. 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-- `hd-browser-picker` — what happens when you click a port-mappings URL+- `hydrogen-browser-picker` — what happens when you click a port-mappings URL ## Bridge ports are dynamic
skills/hydrogen-setup-steps/SKILL.md+15−15@@ -1,14 +1,14 @@ --- name: hydrogen-setup-steps-description: What HD's setup steps did to prepare your workspace — the 28-step cascade that imports the Adom-Workspace golden image, injects your Adom session, wires up the relay, walks the Claude auth gate, and then opens 9 named AI-thread conversations. Use this skill when the user asks "what did setup do", "why is X installed", "re-run a setup step", "what's a virgin reset", or "why did step N fail". Trigger words — setup steps, install steps, setup panel, virgin reset, re-run step, Run All, what did setup do, why is X installed, setup failed, install-tools, hd setup, claude code extension install, gallia install, hd workspace ready.+description: What Hydrogen's setup steps did to prepare your workspace — the 28-step cascade that imports the Adom-Workspace golden image, injects your Adom session, wires up the relay, walks the Claude auth gate, and then opens 9 named AI-thread conversations. Use this skill when the user asks "what did setup do", "why is X installed", "re-run a setup step", "what's a virgin reset", or "why did step N fail". Trigger words — setup steps, install steps, setup panel, virgin reset, re-run step, Run All, what did setup do, why is X installed, setup failed, install-tools, hd setup, claude code extension install, gallia install, hd workspace ready. --- -# HD Setup Steps — what was done to prepare your workspace+# Hydrogen Setup Steps — what was done to prepare your workspace WSL2-runtime version (default). The legacy 24-step Docker cascade (`HD_RUNTIME=docker`) is in the docker/ bucket. -When you first launched Hydrogen (or after a virgin reset), HD ran a 28-step cascade to turn a blank machine into a fully-tooled Adom workspace — the `Adom-Workspace` WSL2 distro. The heavy tooling (code-server, gallia, the Adom CLIs, the Claude Code VS Code extension, VS Code settings, and all `hd-*` skills) is already BAKED into the golden image; setup imports that image, injects your Adom session, wires up the relay, installs the `claude` CLI at runtime (the one thing NOT baked — its self-setup needs a live session), walks the Claude auth gate, then opens the first conversation + 9 named AI-thread conversations. 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 `hd-golden-image` for the baked-image model.+When you first launched Hydrogen (or after a virgin reset), Hydrogen ran a 28-step cascade to turn a blank machine into a fully-tooled Adom workspace — the `Adom-Workspace` WSL2 distro. The heavy tooling (code-server, gallia, the Adom CLIs, the Claude Code VS Code extension, VS Code settings, and all `hd-*` skills) is already BAKED into the golden image; setup imports that image, injects your Adom session, wires up the relay, installs the `claude` CLI at runtime (the one thing NOT baked — its self-setup needs a live session), walks the Claude auth gate, then opens the first conversation + 9 named AI-thread conversations. 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_wsl.rs` (`step_defs_wsl()` / `run_all_wsl()`). `run_all_wsl` is halt-on-failure, resume-not-restart, with per-step 3× auto-retry. In-distro work runs via `wsl -d Adom-Workspace -u adom -- <cmd>` (the distro's DEFAULT user is `adom` per `wsl.conf default=adom`, home `/home/adom`; root via `-u root`). There is NO `docker exec` and NO Docker image anywhere in this flow. @@ -28,7 +28,7 @@ The cascade is executed by `setup_steps_wsl.rs` (`step_defs_wsl()` / `run_all_ws | 10 | test-direct-connect | Prove the fast workspace→desktop command path | | 11 | test-relay | Register the relay with Adom Bridge for file streaming (file transfer + shell exec) | | 12 | test-adom-cli | GATE: carbon path + hydrogen-proxy reachability via adom-cli (6 retries) |-| 13 | install-claude-cli | Install the Claude Code CLI (`claude`) into the distro via the official installer. NOT baked (its self-setup needs a live session) — HD installs it here at runtime, before sign-in, so the editor's Claude Code + the Welcome/thread conversations have a working `claude`. Idempotent (skips if present). |+| 13 | install-claude-cli | Install the Claude Code CLI (`claude`) into the distro via the official installer. NOT baked (its self-setup needs a live session) — Hydrogen installs it here at runtime, before sign-in, so the editor's Claude Code + the Welcome/thread conversations have a working `claude`. Idempotent (skips if present). | | 14 | claude-auth | The single human gate — restore Claude creds or drive the in-editor Claude.ai sign-in via the native browser Browser Picker; runs just before the payoff steps | | 15 | ensure-sse | GATE: confirm the editor browser SSE session is connected so Welcome's webview-open doesn't 409 | | 16 | verify-workspace | GATE: battery confirming the proxy holds a real layout |@@ -43,17 +43,17 @@ The cascade is executed by `setup_steps_wsl.rs` (`step_defs_wsl()` / `run_all_ws | 25 | thread-chip-fetcher | Fresh conversation: install chip-fetcher, show it in a webview, search VL53L8CH | | 26 | thread-tsci | Fresh conversation: adom-tsci builds an RP2040 + USB-C dev board in one prompt, shown in pup | | 27 | verify-setup | GATE (catch-all): independently re-verifies the whole workspace end-to-end; HALTS naming any artifact that isn't actually there |-| 28 | open-welcome | GATE (final): open welcome.html in HD's right pane; hard-fails if the Welcome tab doesn't appear |+| 28 | open-welcome | GATE (final): open welcome.html in Hydrogen's right pane; hard-fails if the Welcome tab doesn't appear | Steps 18–26 (the AI threads) each open a FRESH Claude conversation and human-type a prompt, strictly one at a time. They replaced the old single `eda-discovery` + `instapcb-quote` steps. ### Steps that NO LONGER EXIST (baked into the golden image) -These are NOT setup steps anymore — they are baked at image-build time: `install-gallia`, `install-hd-skills`, `verify-adom-bridge-cli`, `install-claude-ext`, `write-vscode-settings`, `set-trusted-domains`, `clean-layout`. If a user asks "what installed gallia / the Claude extension / my skills / VS Code settings", the answer is: **baked into the golden image at build time, not a setup step.** (Note: `install-claude-cli` is NOT in this list — the `claude` CLI IS a live setup step, since its self-setup needs a live session.) See `hd-golden-image`.+These are NOT setup steps anymore — they are baked at image-build time: `install-gallia`, `install-hydrogen-skills`, `verify-adom-bridge-cli`, `install-claude-ext`, `write-vscode-settings`, `set-trusted-domains`, `clean-layout`. If a user asks "what installed gallia / the Claude extension / my skills / VS Code settings", the answer is: **baked into the golden image at build time, not a setup step.** (Note: `install-claude-cli` is NOT in this list — the `claude` CLI IS a live setup step, since its self-setup needs a live session.) See `hydrogen-golden-image`. ## Common user questions -**"Why is X installed in my workspace?"** → If X is gallia, an Adom CLI, the Claude Code extension, VS Code settings, or an `hd-*` skill, it was **baked into the golden image** — not run as a setup step. (The `claude` CLI is the exception: it's installed at RUNTIME by step 13 `install-claude-cli`.) The setup steps only import the image, inject your session, wire the relay, and walk Claude auth. The setup panel (HD UI → bottom) lists every step with its current status.+**"Why is X installed in my workspace?"** → If X is gallia, an Adom CLI, the Claude Code extension, VS Code settings, or an `hd-*` skill, it was **baked into the golden image** — not run as a setup step. (The `claude` CLI is the exception: it's installed at RUNTIME by step 13 `install-claude-cli`.) The setup steps only import the image, inject your session, wire the relay, and walk Claude auth. The setup panel (Hydrogen UI → bottom) lists every step with its current status. **"Setup failed at step N"** → The setup panel shows the error. Most common failures: step 1 (WSL2 unavailable / Virtual Machine Platform feature off, or the `adom-golden.tar.gz` download), step 12 (test-adom-cli — carbon/hydrogen-proxy not reachable yet), step 13/14 (claude CLI install / Claude credentials expired). Each step has a retry button (and the cascade already retried it 3×). @@ -70,12 +70,12 @@ Virgin reset wipes parts of your workspace so setup can rebuild them cleanly. Th | Install step state (`install_state`) | Marks all steps as pending (`setup-steps-wsl.json`) so they re-run | Always (default on) | | WSL2 distro (`container`) | PRISTINE `wsl --unregister Adom-Workspace` + reimport — deletes the distro AND everything in it, including `/home/adom/project` | Always (default on); your work in `/home/adom/project` is GONE | | Distro tarball (`tarball`, legacy `image`) | Deletes the cached `adom-golden.tar.gz` (full-image re-download) | Rarely — only if the tarball is corrupted |-| Webview storage (`webview_storage`) | Queued wipe, flushed at next HD launch (restart_required) | Rarely |-| VS Code state (`vscode_state`) | Queued wipe, flushed at next HD launch (restart_required) | Rarely |+| Webview storage (`webview_storage`) | Queued wipe, flushed at next Hydrogen launch (restart_required) | Rarely |+| VS Code state (`vscode_state`) | Queued wipe, flushed at next Hydrogen launch (restart_required) | Rarely | | Adom session token (`adom_token`) | Deletes `hydrogen-session.txt`; forces re-login | Rarely | | Claude credentials (`claude_token`) | Deletes the host-side Claude creds backup; forces Claude re-auth | When Claude auth is stuck | -`confirmed_destructive` must be set. After toggling, hit "Wipe Selected", then "Run All" to rebuild. The distro reset backs up Claude creds first UNLESS `claude_token` is checked; the `webview_storage` / `vscode_state` wipes are queued and flushed at the next HD launch (restart_required), not immediate.+`confirmed_destructive` must be set. After toggling, hit "Wipe Selected", then "Run All" to rebuild. The distro reset backs up Claude creds first UNLESS `claude_token` is checked; the `webview_storage` / `vscode_state` wipes are queued and flushed at the next Hydrogen launch (restart_required), not immediate. CRITICAL: the WSL reset ONLY ever runs `wsl --unregister Adom-Workspace` (+ reimport). It never runs global `wsl --shutdown` or `wsl --uninstall` (those would kill the user's other distros, including any Docker Desktop WSL integration), and it performs NO Docker actions and NO reboot for the wipe. @@ -88,19 +88,19 @@ CRITICAL: the WSL reset ONLY ever runs `wsl --unregister Adom-Workspace` (+ reim | `POST /setup/panel/run-virgin-reset` | Trigger virgin reset with the supplied toggle options | | `POST /setup/panel/show` | Open the setup panel from anywhere | -All on HD's control API at `http://127.0.0.1:47084`.+All on Hydrogen's control API at `http://127.0.0.1:47084`. **DEPRECATED — now REFUSED, do not use:** `POST /wsl/unregister`, `POST /setup/virgin-reset`, `POST /setup/run-all`, `POST /setup/run-step`. Use `POST /setup/panel/run-virgin-reset` and `POST /setup/step/<id>` instead. ## Setup state file -Setup writes its state to `%APPDATA%\hydrogen-desktop\setup-steps-wsl.json` (one entry per step with `status: pending|running|done|failed`, output text, percent complete). HD reads this on launch to decide whether the setup panel auto-opens. (The legacy Docker runtime uses `setup-steps.json`.)+Setup writes its state to `%APPDATA%\hydrogen-desktop\setup-steps-wsl.json` (one entry per step with `status: pending|running|done|failed`, output text, percent complete). Hydrogen reads this on launch to decide whether the setup panel auto-opens. (The legacy Docker runtime uses `setup-steps.json`.) ## Related skills -- `hd-golden-image` — the baked-image model: what's pre-installed in `adom-golden.tar.gz` vs. what setup does+- `hydrogen-golden-image` — the baked-image model: what's pre-installed in `adom-golden.tar.gz` vs. what setup does - `hydrogen-container` — the WSL2 distro and runtime that setup configures-- `hydrogen-networking` — how the distro reaches the host (`127.0.0.1` via WSL2 mirrored networking; live control URL in `~/.adom/hd-control-url`) and how ports forward-- `hd-browser-picker` — used by step 14 (claude-auth) for the Claude auth OAuth flow+- `hydrogen-networking` — how the distro reaches the host (`127.0.0.1` via WSL2 mirrored networking; live control URL in `~/.adom/hydrogen-control-url`) and how ports forward+- `hydrogen-browser-picker` — used by step 14 (claude-auth) for the Claude auth OAuth flow - `hydrogen-adom-auth` — how the Adom session token (step 5) gets injected - `hydrogen-volume` — where your files live in the distro and what survives a virgin reset (or doesn't)
skills/hydrogen-setup/SKILL.md+12−12@@ -1,7 +1,7 @@ --- name: hydrogen-setup description: >- HD setup panel: 27 install steps, Run All, Rollback All, Virgin Reset with+ Hydrogen setup panel: 27 install steps, Run All, Rollback All, Virgin Reset with toggles, and automated testing patterns. MUST READ before running setup, testing steps, or doing virgin resets. Covers the step list, the virgin reset toggle panel, how to keep auth during resets, and how Run All handles@@ -16,13 +16,13 @@ WSL2-runtime version (default). The legacy 24-step Docker cascade ## Zero-Click Goal -The HD setup process targets ZERO manual clicks for the user. The heavy+The Hydrogen setup process targets ZERO manual clicks for the user. The heavy lifting is already done at image-build time: the `Adom-Workspace` golden image ships with code-server, gallia, the 8 Adom CLIs, the claude CLI + Code extension, VS Code settings, and all `hd-*` skills BAKED IN. Setup just imports that image, injects the user's session, wires up the relay, and walks-the single human auth gate. If something is missing, HD downloads it — never-tell the user to install something manually. See the `hd-golden-image` skill+the single human auth gate. If something is missing, Hydrogen downloads it — never+tell the user to install something manually. See the `hydrogen-golden-image` skill for the baked-image model. ## The 27 Install Steps@@ -55,17 +55,17 @@ Adom-Workspace`. | 16 | welcome | Opens Claude Code, authenticates if needed, human-types the first prompt | ✗ | | 17-25 | thread-* (9) | Nine FRESH Claude conversations, one at a time: parts-search, kicad, fusion360, altium, pup, native-browser, google, chip-fetcher, adom-tsci. Replaced the old eda-discovery + instapcb-quote steps | ✗ | | 26 | verify-setup | GATE (catch-all): independently re-verifies the whole workspace end-to-end; HALTS naming any missing artifact | ✗ |-| 27 | open-welcome | GATE (final): opens welcome.html in HD's right pane; hard-fails if the Welcome tab doesn't appear | ✗ |+| 27 | open-welcome | GATE (final): opens welcome.html in Hydrogen's right pane; hard-fails if the Welcome tab doesn't appear | ✗ | ### Steps that NO LONGER EXIST (baked into the golden image) These are NOT setup steps anymore — they are baked at image-build time and-must not be listed or "run": `install-gallia`, `install-hd-skills`,+must not be listed or "run": `install-gallia`, `install-hydrogen-skills`, `verify-adom-bridge-cli`, `install-claude-ext`, `write-vscode-settings`, `set-trusted-domains`, `clean-layout`. gallia, the 8 Adom CLIs, the Claude Code VS Code extension (the claude CLI is runtime step 12, NOT baked), code-server, settings, and all `hd-*` skills are baked into the golden image. See-`hd-golden-image`.+`hydrogen-golden-image`. ## Panel Buttons @@ -95,8 +95,8 @@ live status badge showing the current state. The ONLY programmatic trigger is | Install step state (`install_state`) | Resets all 28 steps to pending (`setup-steps-wsl.json`) | CLEAN / EXISTS | | WSL2 distro (`container`) | PRISTINE `wsl --unregister Adom-Workspace` + reimport (ONLY that distro) | GONE / RUNNING / EXISTS | | Distro tarball (`tarball`, legacy `image`) | Deletes cached `adom-golden.tar.gz` (full image re-download) | CACHED / GONE |-| Webview storage (`webview_storage`) | Queued wipe, flushed at next HD launch (restart_required) | CLEAN / EXISTS |-| VS Code state (`vscode_state`) | Queued wipe, flushed at next HD launch (restart_required) | CLEAN / EXISTS |+| Webview storage (`webview_storage`) | Queued wipe, flushed at next Hydrogen launch (restart_required) | CLEAN / EXISTS |+| VS Code state (`vscode_state`) | Queued wipe, flushed at next Hydrogen launch (restart_required) | CLEAN / EXISTS | | Adom session token (`adom_token`) | Deletes `hydrogen-session.txt` | CLEAN / EXISTS | | Claude credentials (`claude_token`) | Deletes the host-side Claude creds backup | CLEAN / EXISTS | @@ -105,7 +105,7 @@ Selected"** at the bottom executes the reset for all checked toggles. The distro reset is a PRISTINE `wsl --unregister` + reimport — it backs up Claude creds first UNLESS `claude_token` is checked. The `webview_storage` /-`vscode_state` wipes are queued and flushed at the next HD launch+`vscode_state` wipes are queued and flushed at the next Hydrogen launch (restart_required), NOT immediate; there is no reboot for the wipe. CRITICAL — the WSL virgin reset only ever touches `Adom-Workspace`. It runs@@ -182,12 +182,12 @@ via the native browser Browser Picker. Runs LAST before the payoff steps. `ensure-sse` confirms the editor browser SSE session is connected (so the Welcome webview-open doesn't 409); `verify-workspace` confirms the proxy holds a real layout; `welcome` opens Claude Code and sends the first prompt; the-final `open-welcome` gate opens welcome.html in HD's right pane and HARD-FAILS+final `open-welcome` gate opens welcome.html in Hydrogen's right pane and HARD-FAILS if the Welcome tab doesn't appear. > Note: gallia, the Adom CLIs, the claude CLI + Code extension, VS Code > settings, and `hd-*` skills are NOT setup steps — they are baked into-> `adom-golden.tar.gz`. See `hd-golden-image`.+> `adom-golden.tar.gz`. See `hydrogen-golden-image`. ## Distro Recreation
skills/hydrogen-topology/SKILL.md+12−12@@ -1,11 +1,11 @@ --- name: hydrogen-topology description: >- MUST READ before ANY HD work. Explains the three-layer topology: cloud- Docker (where Claude runs), Windows machine (where HD + Adom Bridge run),- and the HD local WSL2 workspace (the Adom-Workspace distro). Every command+ MUST READ before ANY Hydrogen work. Explains the three-layer topology: cloud+ Docker (where Claude runs), Windows machine (where Hydrogen + Adom Bridge run),+ and the Hydrogen local WSL2 workspace (the Adom-Workspace distro). Every command you run goes through the relay to Windows. You CANNOT directly access the- WSL2 distro — you must shell through Windows. Trigger words — HD topology,+ WSL2 distro — you must shell through Windows. Trigger words — Hydrogen topology, cloud vs local, wsl exec, where am I, which workspace, adom-bridge-cli relay, test from container, three tiers, architecture, windows machine. ---@@ -23,7 +23,7 @@ CLI relay. There are THREE separate environments: ### 1. Cloud Docker (where you run) - Your shell, your filesystem, your git repos - `adom-bridge-cli` CLI connects to Adom Bridge on Windows via relay-- This container has NOTHING to do with HD's local WSL2 workspace+- This container has NOTHING to do with Hydrogen's local WSL2 workspace - Restarting the WSL2 distro on Windows does NOT affect you - You can freely `git push`, edit code, run builds here @@ -34,7 +34,7 @@ CLI relay. There are THREE separate environments: - You reach this via `adom-bridge-cli shell_execute '{"command":"..."}'` - Commands run in `cmd.exe` on Windows -### 3. HD Local WSL2 Workspace (the `Adom-Workspace` distro)+### 3. Hydrogen Local WSL2 Workspace (the `Adom-Workspace` distro) - Distro name: `Adom-Workspace` (fixed — no random suffix, no container name) - Runs code-server, adom-bridge-cli CLI, relay server - You reach this via: `adom-bridge-cli shell_execute '{"command":"wsl -d Adom-Workspace -u adom -- <cmd>"}'`@@ -47,7 +47,7 @@ CLI relay. There are THREE separate environments: adom-bridge-cli shell_execute '{"command":"dir C:\\Github"}' ``` -### Run something in the HD local WSL2 workspace+### Run something in the Hydrogen local WSL2 workspace ```bash adom-bridge-cli shell_execute '{"command":"wsl -d Adom-Workspace -u adom -- ls /home/adom"}' ```@@ -58,7 +58,7 @@ adom-bridge-cli shell_execute '{"command":"wsl -d Adom-Workspace -u adom -- adom ``` This tests the FULL chain: distro → local relay → Adom Bridge on Windows. -### Screenshot HD window+### Screenshot Hydrogen window ```bash adom-bridge-cli desktop_screenshot_window '{"hwnd":HWND}' ```@@ -90,7 +90,7 @@ Cloud adom-bridge-cli CLI → back through relay to your CLI ``` -For the HD local WSL2 workspace, there's a SECOND relay:+For the Hydrogen local WSL2 workspace, there's a SECOND relay: ``` Workspace's adom-bridge-cli CLI → local relay (distro :8765)@@ -100,9 +100,9 @@ Workspace's adom-bridge-cli CLI → returns through same chain ``` -## Critical Setup Steps for the HD Local WSL2 Workspace+## Critical Setup Steps for the Hydrogen Local WSL2 Workspace -The HD install flow MUST verify this chain works:+The Hydrogen install flow MUST verify this chain works: 1. **Verify Adom Bridge running on Windows** — probe port 8770 If not running: tell user to install from wiki and launch it@@ -115,7 +115,7 @@ The HD install flow MUST verify this chain works: ## NEVER Do These -1. **NEVER confuse your cloud Docker with the HD local WSL2 workspace.**+1. **NEVER confuse your cloud Docker with the Hydrogen local WSL2 workspace.** `curl http://127.0.0.1:8766/health` hits YOUR relay, not the workspace's. 2. **NEVER try to `wsl -d Adom-Workspace` from your shell.** The distro lives on Windows WSL2, not here.
skills/hydrogen-volume/SKILL.md+10−10@@ -1,9 +1,9 @@ --- name: hydrogen-volume-description: How HD's WSL2 workspace storage is laid out — what's persistent, what's ephemeral, where your work lives, what survives a workspace restart vs a virgin reset, and how to access your workspace files from your Windows host. Use when the user asks "where are my files", "did I lose my work", "how do I copy a file out of the workspace", or "what happens to my code if I virgin reset". Trigger words — wsl filesystem, hd volume, where are my files, workspace files, persistent storage, lost my work, /home/adom/project, distro filesystem, wsl export, copy file out of workspace, where is my code, workspace backup, wsl unregister.+description: How Hydrogen's WSL2 workspace storage is laid out — what's persistent, what's ephemeral, where your work lives, what survives a workspace restart vs a virgin reset, and how to access your workspace files from your Windows host. Use when the user asks "where are my files", "did I lose my work", "how do I copy a file out of the workspace", or "what happens to my code if I virgin reset". Trigger words — wsl filesystem, hd volume, where are my files, workspace files, persistent storage, lost my work, /home/adom/project, distro filesystem, wsl export, copy file out of workspace, where is my code, workspace backup, wsl unregister. --- -# HD Workspace Storage — what persists, what doesn't+# Hydrogen Workspace Storage — what persists, what doesn't WSL2-runtime version (default). Legacy Docker container runtime (`HD_RUNTIME=docker`) is in the docker/ bucket. @@ -17,7 +17,7 @@ Your work lives in the `Adom-Workspace` WSL2 distro at `/home/adom/project`. The | Your work path | `/home/adom/project` (plain directory in the distro's ext4 fs) | | Backing store | The distro's virtual disk (`ext4.vhdx`) inside the WSL2 LxssManager store on Windows | | On-disk location (Windows) | Under `%LOCALAPPDATA%\...\Adom-Workspace\` — but you don't poke at the vhdx directly; use `\\wsl$\Adom-Workspace\...` (see below) |-| Persistence | Survives workspace restart, HD restart, and Windows reboot. Persists as long as the distro is **registered** with WSL. |+| Persistence | Survives workspace restart, Hydrogen restart, and Windows reboot. Persists as long as the distro is **registered** with WSL. | There is **no named volume to delete separately** — the project files and the OS image are one and the same ext4 filesystem. The only thing that wipes `/home/adom/project` is unregistering the distro. @@ -25,10 +25,10 @@ There is **no named volume to delete separately** — the project files and the | Path inside the distro | Persists across a tarball re-import? | Notes | |------------------------|---------------------------------------|-------|-| `/home/adom/project/` | **Yes** — HD exports `/home/adom` before re-importing the golden image on a version bump, then restores it | This is your code. Put everything important here. |+| `/home/adom/project/` | **Yes** — Hydrogen exports `/home/adom` before re-importing the golden image on a version bump, then restores it | This is your code. Put everything important here. | | `~/.local/share/code-server/extensions/` | **Yes** within the distro — BAKED into the golden image, restored on tarball re-import | Not a setup step; baked at image-build time | | `~/.local/share/code-server/User/settings.json` | **Yes** within the distro — BAKED into the golden image | Not a setup step; baked at image-build time |-| `~/.claude/` (skills, credentials) | Skills are BAKED into the golden image (restored on re-import); credentials are restored by the `claude-auth` setup step from a host-side backup | HD skills are baked FLAT into `~/.claude/skills/<name>/` |+| `~/.claude/` (skills, credentials) | Skills are BAKED into the golden image (restored on re-import); credentials are restored by the `claude-auth` setup step from a host-side backup | Hydrogen skills are baked FLAT into `~/.claude/skills/<name>/` | | `/tmp/` | **No** | Ephemeral | | `/etc/`, `/usr/`, system stuff | Lives in the same ext4 fs, but is overwritten on a tarball version bump | Treat as part of the workspace image | @@ -36,7 +36,7 @@ There is **no named volume to delete separately** — the project files and the ## What survives each virgin-reset choice -When you open Virgin Reset (HD setup panel), the checkbox toggles control which artifacts get deleted:+When you open Virgin Reset (Hydrogen setup panel), the checkbox toggles control which artifacts get deleted: | Toggle ON means: | Result | |------------------|--------|@@ -95,16 +95,16 @@ wsl --export Adom-Workspace C:\Users\john\Downloads\adom-workspace-backup.tar wsl --import Adom-Workspace C:\WSL\Adom-Workspace C:\Users\john\Downloads\adom-workspace-backup.tar ``` -This is exactly the mechanism HD's own tarball-migration uses: on a tarball version bump it `wsl --export`s `/home/adom` first, then re-imports the new base and restores your work.+This is exactly the mechanism Hydrogen's own tarball-migration uses: on a tarball version bump it `wsl --export`s `/home/adom` first, then re-imports the new base and restores your work. Or, for just a few files, copy them out first via `\\wsl$\Adom-Workspace\...` or `/mnt/c/...`. ## Why a distro filesystem (no named volume, no bind mount)? -HD keeps your work directly inside the `Adom-Workspace` ext4 filesystem rather than a Docker named volume or a bind mount of a Windows path. This:+Hydrogen keeps your work directly inside the `Adom-Workspace` ext4 filesystem rather than a Docker named volume or a bind mount of a Windows path. This: - Gives native Linux ext4 I/O — much faster than crossing the Windows ↔ WSL2 filesystem boundary - Avoids line-ending and permission issues that bind mounts of Windows paths often have-- Lets HD wipe + re-import the base image (on a tarball bump) without losing your code — it `wsl --export`s `/home/adom` first+- Lets Hydrogen wipe + re-import the base image (on a tarball bump) without losing your code — it `wsl --export`s `/home/adom` first The bonus over the legacy Docker runtime: you **can** open the files directly in Windows Explorer at `\\wsl$\Adom-Workspace\...`. @@ -112,4 +112,4 @@ The bonus over the legacy Docker runtime: you **can** open the files directly in - `hydrogen-container` — the `Adom-Workspace` distro whose filesystem holds your work - `hydrogen-topology` — the three-tier topology; tier 3 is this WSL2 distro-- `hd-golden-image` — what's baked into `adom-golden.tar.gz` (extensions, settings, skills) vs. what setup does+- `hydrogen-golden-image` — what's baked into `adom-golden.tar.gz` (extensions, settings, skills) vs. what setup does
skills/hydrogen-workspace-lifecycle/SKILL.md+17−17@@ -1,6 +1,6 @@ --- name: hydrogen-workspace-lifecycle-description: WSL2 distro (`Adom-Workspace`) lifecycle management for Hydrogen on Windows. Import/export/unregister/terminate, code-server-as-HD-child, the resume reality-check, recovery after sleep/hibernate, and every hard-won rule about what NOT to do — above all, NEVER run global WSL operations; touch ONLY Adom-Workspace so a co-installed Docker Desktop WSL integration stays safe. MUST READ before any workspace operation. Trigger words — wsl, workspace, distro, Adom-Workspace, restart workspace, terminate distro, unregister, wsl --import, wsl --unregister, code-server, workspace broken, workspace unhealthy, wsl hung, fix workspace, /wsl/status.+description: WSL2 distro (`Adom-Workspace`) lifecycle management for Hydrogen on Windows. Import/export/unregister/terminate, code-server-as-Hydrogen-child, the resume reality-check, recovery after sleep/hibernate, and every hard-won rule about what NOT to do — above all, NEVER run global WSL operations; touch ONLY Adom-Workspace so a co-installed Docker Desktop WSL integration stays safe. MUST READ before any workspace operation. Trigger words — wsl, workspace, distro, Adom-Workspace, restart workspace, terminate distro, unregister, wsl --import, wsl --unregister, code-server, workspace broken, workspace unhealthy, wsl hung, fix workspace, /wsl/status. --- # Hydrogen — WSL2 Workspace Lifecycle@@ -27,8 +27,8 @@ Forbidden, no exceptions: proxy into every distro via the shared `/mnt/wsl` namespace (`/mnt/wsl/docker-desktop/docker-desktop-user-distro`). Any global WSL teardown makes that path vanish and pops a "Docker Desktop - Ubuntu: WSL integration unexpectedly-stopped" dialog. It's harmless to HD's own `Adom-Workspace`, but it looks to the user-like HD broke their Docker — terrible first-run UX. So every HD operation must be+stopped" dialog. It's harmless to Hydrogen's own `Adom-Workspace`, but it looks to the user+like Hydrogen broke their Docker — terrible first-run UX. So every Hydrogen operation must be scoped to `Adom-Workspace` and nothing else. Allowed, scoped operations:@@ -57,15 +57,15 @@ then `wsl --import Adom-Workspace <dir> adom-golden.tar.gz`, then start code-ser Log proof: `[wsl-tarball] downloaded … SHA256 OK` → `[setup] WSL setup_and_start completed` and `wsl -l -v` shows `Adom-Workspace Running 2`. -### code-server is an HD-OWNED CHILD process-code-server (`CODE_SERVER_CHILD` in `runtime/wsl.rs`) runs as a child of HD, deliberately-tied to HD's lifetime — **NOT a detached `nohup`** (a detached process dies when WSL-tears down the session anyway). Consequence: every HD restart (rebuild / crash /-relaunch) orphans the old code-server, so a fresh HD can come up with the distro+### code-server is an Hydrogen-OWNED CHILD process+code-server (`CODE_SERVER_CHILD` in `runtime/wsl.rs`) runs as a child of Hydrogen, deliberately+tied to Hydrogen's lifetime — **NOT a detached `nohup`** (a detached process dies when WSL+tears down the session anyway). Consequence: every Hydrogen restart (rebuild / crash /+relaunch) orphans the old code-server, so a fresh Hydrogen can come up with the distro `Running` but the editor DEAD ("Starting AI Environment" forever) even when setup is otherwise complete. -Fix (already in HD): HD **re-ensures code-server on every launch**+Fix (already in Hydrogen): Hydrogen **re-ensures code-server on every launch** (`[wsl-startup] re-ensured code-server on launch`). And the resume reality-check in `run_all_wsl` requires code-server reachable on the host port **7380** — not just "distro registered" — before it trusts the workspace as ready.@@ -90,8 +90,8 @@ with `wsl --import Adom-Workspace <dir> <file>.tar`. (Scoped to this distro, so ## Control API -The HD control API is on loopback **`http://127.0.0.1:<dynamic>`** (NOT 9001). The-port is dynamic per launch — read the live URL from `~/.adom/hd-control-url`. From+The Hydrogen control API is on loopback **`http://127.0.0.1:<dynamic>`** (NOT 9001). The+port is dynamic per launch — read the live URL from `~/.adom/hydrogen-control-url`. From inside the distro, reach the host at the same `127.0.0.1` URL: WSL2 mirrored networking shares loopback with the Windows host. @@ -102,7 +102,7 @@ networking shares loopback with the Windows host. | `GET /container-stats` | Live CPU/RAM/disk from the `workspace_stats()` probe (see hydrogen-container-stats) | ```bash-BASE="$(cat ~/.adom/hd-control-url)" # http://127.0.0.1:<dynamic>+BASE="$(cat ~/.adom/hydrogen-control-url)" # http://127.0.0.1:<dynamic> # Workspace status (from inside the distro) curl -s "$BASE/wsl/status"@@ -114,17 +114,17 @@ curl -s -X POST "$BASE/wsl/unregister" ## Diagnosing Workspace Problems ### "Workspace unhealthy" / editor stuck on "Starting AI Environment"-- **Cause**: code-server child was orphaned by an HD restart, or the distro went+- **Cause**: code-server child was orphaned by an Hydrogen restart, or the distro went unreachable after sleep.-- **Check**: `[wsl] Workspace unhealthy …` in the HD log (the real signal). NOTE: a+- **Check**: `[wsl] Workspace unhealthy …` in the Hydrogen log (the real signal). NOTE: a `[docker] Container runtime unhealthy …` line under WSL is **benign noise** — a leftover heartbeat with no container bound. Ignore it; look at the `[wsl]` line. - **Fix**: Restart Workspace (Adom menu) = `wsl --terminate Adom-Workspace` + re-ensure code-server. Verify code-server answers on :7380. ### Distro `Running` but editor dead-- **Cause**: code-server (HD's child) isn't up even though `wsl -l -v` shows Running.-- **Fix**: relaunch HD (it re-ensures code-server on launch), or Restart Workspace.+- **Cause**: code-server (Hydrogen's child) isn't up even though `wsl -l -v` shows Running.+- **Fix**: relaunch Hydrogen (it re-ensures code-server on launch), or Restart Workspace. Confirm via the resume reality-check — code-server reachable on :7380, not just "distro registered." @@ -140,7 +140,7 @@ When the workspace is broken, follow this order: 1. **Check WSL2 itself**: `wsl --status` (NOT `wsl --shutdown`). 2. **Check the distro**: `wsl -l -v` — is `Adom-Workspace` listed and Running? 3. **If Running but editor dead**: code-server child orphaned → Restart Workspace- (`wsl --terminate Adom-Workspace` + re-ensure code-server), or relaunch HD.+ (`wsl --terminate Adom-Workspace` + re-ensure code-server), or relaunch Hydrogen. 4. **Verify code-server**: it must answer on host :7380 (the resume reality-check). 5. **Last resort (destructive)**: `wsl --unregister Adom-Workspace` then re-import via `setup_and_start` — wipes the distro and re-imports `adom-golden.tar.gz`.
skills/hydrogen-workspace-monitoring/SKILL.md+9−9@@ -12,7 +12,7 @@ description: > reachable, lifecycle dialog, workspace state, Adom-Workspace running. --- -# HD Workspace Monitoring+# Hydrogen Workspace Monitoring > This is the WSL2-runtime version (default). The legacy Docker equivalent > (`HD_RUNTIME=docker`) is in the docker/ bucket.@@ -20,15 +20,15 @@ description: > ## Architecture Under the WSL2 runtime the workspace is the **`Adom-Workspace` distro** (imported via-`wsl --import`), not a Docker container. HD monitors workspace health at two levels:+`wsl --import`), not a Docker container. Hydrogen monitors workspace health at two levels: 1. **WSL2 available** — is WSL2 itself installed and responding on this machine? 2. **Workspace healthy** — is `Adom-Workspace` registered AND Running AND is code-server reachable on host port **7380**? The second level is a real reachability check, not just "is the distro registered."-A resume reality-check (after sleep, or after an HD rebuild/relaunch) requires-code-server to actually answer before HD trusts the workspace as healthy — a distro+A resume reality-check (after sleep, or after an Hydrogen rebuild/relaunch) requires+code-server to actually answer before Hydrogen trusts the workspace as healthy — a distro can be `Running` while code-server is dead. The VS Code panel (`PanelVisualStudioCode.svelte`) polls workspace state every 15s@@ -64,7 +64,7 @@ running") become WSL/distro states under this runtime. ### 1. WSL2 Not Available (red dot) - **When**: WSL2 itself is not installed / not responding (level-1 health fails) - **Message**: "WSL2 is required but not available."-- **Action**: "Run Setup Steps" button → dispatches `hd-show-setup` event (which walks+- **Action**: "Run Setup Steps" button → dispatches `hydrogen-show-setup` event (which walks the user through enabling WSL2) - **Color**: Red dot in header @@ -90,11 +90,11 @@ delegates to `WslDistroRuntime::setup_and_start`: Adom-Workspace` + start code-server. - If the distro is present but code-server is down, it just (re-)starts code-server. -Importantly, code-server runs as an **HD-owned child process** (not a detached-`nohup`) — it dies with HD. So HD also **re-ensures code-server on every launch**+Importantly, code-server runs as an **Hydrogen-owned child process** (not a detached+`nohup`) — it dies with Hydrogen. So Hydrogen also **re-ensures code-server on every launch** (look for `[wsl-startup] re-ensured code-server on launch` in the log). Without that,-a freshly relaunched HD would show the distro Running but the editor stuck on-"Starting AI Environment" forever, because the previous HD's code-server child was+a freshly relaunched Hydrogen would show the distro Running but the editor stuck on+"Starting AI Environment" forever, because the previous Hydrogen's code-server child was orphaned. See [hydrogen-workspace-lifecycle](../hydrogen-workspace-lifecycle/SKILL.md) for the full lifecycle detail.